2017-07-06 4 views
1

Warum ergeben sich folgende Ergebnisse?sprintf Rundung

echo 2.55 * 100; 
echo sprintf(' %d', 2.55 * 100); 

output:

255 254 
+0

[Ausgangspunkt] (http://floating-point-gui.de/) –

+0

@MarkBaker Das ist kein Ausgangspunkt für sein Problem. – Xatenev

+0

Mögliches Duplikat von [Ist Fließkomma-Mathematik gebrochen?] (Https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Qirel

Antwort

2

2.55 * 100 Da in der Basis 2 befestigte Größe Darstellung nicht eine ganze Zahl ist und %d nicht rund:

var_dump(sprintf('%d', 1.99)); 
string(1) "1" 
float(254.99999999999997158) 

Im Gegensatz zu printf(), echo $numeric_variable hat keinen eigenen Mechanismus von String-Nummer zu konvertieren. Es wird nur mit der default rules zur Zeichenfolge umgewandelt, also ist es identisch mit (string)$numeric_variable oder strval($numeric_variable). In diesem Fall gilt:

  • Da Variablentyp float ist versucht es, einen Schwimmer darzustellen (das impliziert von binären IEEE 754 Umwandeln in dezimal).
  • Es liest die precision Richtlinie die Darstellung zur Feinabstimmung:

    Die Anzahl der signifikanten Stellen in Gleitkommazahlen angezeigt. -1 bedeutet, dass ein erweiterter Algorithmus zum Runden solcher Zahlen verwendet wird.

Um den Fehler in IEEE 754 Dezimal-Umwandlung, string Guss Runden wie notwendig zu reduzieren. In meinem Computer ist precision14 Standard, was ziemlich nah an der Anzahl der Neunen ist.

+0

@Xatenev Bitte beachten Sie, dass es viele 9's gibt. Sie verlassen sich auf die Standardpräzision ('ini_get ('precision')'); –

+0

Habe gerade meinen Fehler erkannt. +1 – Xatenev

+0

Danke, ich verstehe warum 'echo sprintf ('% d', 2.55 * 100);' würde 254 drucken. Was ist mit dem anderen Fall? Was ist daran anders? – DrRumpus