У меня ужасное время, убеждающее себя, что я здесь сделал, хорошая идея. Конкретный раздел, который я считаю неуместным, таков:
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 (представляющие микросекунды), используя оператор сложения ( + ), я всегда получаю 123456789.099. Даже при отливке целого числа на float результат будет таким же.
Есть ли решение для этой проблемы: 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);
Если вы должны были изучить $ start или $ end, прежде чем вычесть один из другого, может показаться, что они округлены до сотых позиций. Это не тот случай. Кажется, что произвольная точность поддерживается для арифметики, пока дисплей ограничен.