У меня ужасное время, чтобы убедить себя в том, что я здесь сделал, это хорошая идея. Конкретный раздел, который я считаю нежелательным:
return ((float)($now+$sec).'.'.$mic);
Чтобы сохранить точность с плавающей запятой, я вынужден использовать библиотеки BC или GMP (ни одна из которых не всегда доступна). В этом случае я прибегал к глушению чисел вместе с конкатенацией строк.
<?php
// return the current time, with microseconds
function tick() {
list($sec, $mic, $now) = sscanf(microtime(), "%d.%d %d");
return ((float)($now+$sec).'.'.$mic);
}
// compare the two given times and return the difference
function elapsed($start, $end) {
$diff = $end-$start;
// the difference was negligible
if($diff < 0.0001)
return 0.0;
return $diff;
}
// get our start time
$start = tick();
// sleep for 2 seconds (should be ever slightly more than '2' when measured)
sleep(2);
// get our end time
$end = tick();
$elapsed = elapsed($start, $end);
// should produce output similar to: float(2.00113797188)
var_dump($elapsed);
?>
Если я попытаюсь добавить два числа, например 123456789 (представляющих временную метку) и 0.0987654321 (представляющих микросекунды), используя оператор сложения ( + ) I неизменно в конечном итоге с 123456789.099. Даже при использовании целого числа с плавающей точкой результат остается тем же.
Есть ли решение для этой проблемы, которое 1) не является хаком и 2) не включает в себя конкатенацию строк? Мне не нужно прибегать к искаженному коду такого рода, чтобы получить точную временную метку с микросекундным разрешением.
Редактировать: Как объяснил С. Гериг, числа с плавающей запятой в PHP иногда могут быть немного сложными для отображения. «Точность», указанная в конфигурации PHP, относится к отображению. Фактические значения не округлены, как я думал. Гораздо более простое решение для приведенного выше кода будет выглядеть так:
// return the current time, with microseconds
function tick() {
return microtime(true);
}
// compare the two given times and return the difference
function elapsed($start, $end) {
return $end-$start;
}
// get our start time
$start = tick();
// sleep for 2 seconds (should be ever slightly more than '2' when measured)
sleep(2);
// get our end time
$end = tick();
$elapsed = elapsed($start, $end);
// should produce output similar to: float(2.00113797188)
var_dump($elapsed);
Если вы должны были проверить $ начало или $ конец , прежде чем вычесть одно из другого, может показаться, что они были округлены до сотых долей. Это не вариант. Кажется, что произвольная точность сохраняется для арифметики, в то время как отображение ограничено.