Ich habe eine schreckliche Zeit, mich selbst zu überzeugen, was ich hier getan habe, ist eine gute Idee. Der spezifische Abschnitt I zu beanstanden ist:Ungenaue Zahlen mit Mikrozeit und Fließkomma-Addition in PHP
return ((float)($now+$sec).'.'.$mic);
Um die Gleitkommagenauigkeit zu erhalten, bin ich gezwungen, entweder wieder auf dem BC oder GMP-Bibliotheken fällt (von denen keiner ist immer verfügbar). In diesem Fall habe ich versucht, die Zahlen zusammen mit der String-Verkettung einzufangen.
<?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);
?>
Wenn ich Versuch, zwei Zahlen zu addieren, wie (das einen Zeitstempel) und 0,0987654321 (repräsentiereMikroSekunden), die Zugabe Operator ( +) I unveränderlich mit 123456789,099 enden. Auch wenn die Ganzzahl in float umgewandelt wird, ist das Ergebnis dasselbe.
Gibt es eine Lösung für dieses Problem, die 1) kein Hack ist und 2) keine String-Verkettung beinhaltet? Ich sollte nicht auf diese Art von verworrenem Code zurückgreifen müssen, um einen genauen Zeitstempel mit Mikrosekundenauflösung zu erhalten.
Bearbeiten: Wie S. Gehrig erklärt hat, können Fließkommazahlen in PHP manchmal etwas knifflig dargestellt werden. Die in der PHP-Konfiguration angegebene "Genauigkeit" bezieht sich auf die Anzeige. Die tatsächlichen Werte sind nicht abgerundet, wie ich dachte. Eine weitaus einfachere Lösung für den obigen Code würde wie so aussehen:
// 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);
Wenn Sie $ zu untersuchen sind beginnen oder $ beenden, bevor eine von dem anderen subtrahiert wird, könnte es scheint sie auf die Hundertstel gerundet wurden Position. Das ist nicht der Fall. Es scheint, dass willkürliche Genauigkeit für Arithmetik beibehalten wird, während die Anzeige begrenzt ist.
würde ich, aber die Präzision ist auf 2 Stellen gerundet und es scheint nicht eine Möglichkeit, dies zu ändern. Standardmäßig beträgt die Genauigkeit von PHP 12 Stellen ... diese Funktion wird von dieser Funktion jedoch nicht berücksichtigt. Überprüfen Sie es mit: php -r 'echo microtime (wahr);' Ich habe keine Ahnung, was bewirkt, dass es so rund wird. – spligak
Die Genauigkeit von 12 Dezimalstellen für Float enthält die Dezimalstellen vor dem Komma - also ist die Präzision von 12 Stellen genau das, was Sie sehen. –
Dies ist nur ein Anzeigeproblem und wird von der Konfigurationseinstellung 'precision' gesteuert: http://us2.php.net/manual/en/ini.core.php#ini.precision. Intern hat ein Float eine Genauigkeit von etwa 14 Dezimalziffern. –