2011-01-10 17 views
1

In PHP, ich weiß, wir sollten nicht tun math auf Floats ohne Dinge wie bcmath, aber ist der bloße Akt Casting eine Zeichenfolge zu float destructive?Ist Gießen zu schweben destruktiv?

Werden Ausdrücke wie (float)'5.111' == '5.111' immer wahr? Oder wird die Besetzung selbst dies in etwas wie 5.1110000000000199837 ändern, wie die Zahl konvertiert wird?

Der Hauptgrund ist, genau wie ich (int) verwenden, um ganzzahlige Werte in eine Datenbank zu gehen, möchte ich (float) auf die gleiche Weise verwenden, ohne auf Anführungszeichen und meine Escape-Funktion angewiesen zu sein.

+0

es ist besser, sich auf Zitate wäre. Vor allem, weil Sie keine Floats verwenden müssen, sondern ** dezimal **. Es gibt nichts wirklich Schlechtes in Anführungszeichen und behandelt ALLE Daten auf die gleiche Art und Weise (als Strings). –

+0

Ja, wenn Sie Ihre Zeichenkette in einen Float umwandeln, ändert sich ihr Wert. Die Frage zu google ist: "Warum ist' 0.1' plus '0.2' nicht gleich' 0.3 'in Fließkomma-Arithmetik in allen Programmiersprachen? "Die Antwort ist, weil der Computer nicht genau 0.2 in Software mit Base-2-Binärzahlen darstellen kann. Hier ist ein großes Video, das das Problem erklärt: https://www.youtube .com/watch? v = PZRI1IfStY0 –

Antwort

1

NO, Casting zu einem Schwimmer ist fast immer destruktiv.

In Ihrem Beispiel 5.111 binär dargestellt ist:

101.00011100011010100111111011111001110110110010001011010000111001... 

Ein Schwimmer würde 23 Ziffern speichern:

101.0001110001101010011 
(5.1109981536865234375) 

Ein Doppel würde 52 Ziffern speichern:

101.0001110001101010011111101111100111011011001000101 
(5.1109999999999988773424774990417063236236572265625) 

In In diesem Fall gäbe es keinen Unterschied. Bei größeren Zahlen kann dies jedoch Auswirkungen auf die Anzeige haben.

Zum Beispiel:

1025,4995

double:

10000000001.011111111101111100111011011001000101101 
(1025.499499999999898136593401432037353515625) 

float:

10000000001.011111111101 
(1025.499267578125) 

Sie die Präzision sehen beginnt dramatisch nach etwa 8 Stellen fallen weg .

zu 1025,4995 würde rund um die Doppel während der Schwimmer 1025,4993

+0

Das betrifft mich jetzt wirklich, weil 'number_format' die Eingabe in float umwandelt, genau wie' money_format' ... – Andrew

+0

Ich glaube nicht, dass ich Geld zum Floaten werfen würde ... aber es hängt davon ab, was du tust ob es im praktischen Sinn wichtig ist. Wenn Sie mit Zahlen unter 10000.00 arbeiten und Sie nur Penny-Präzision benötigen, ist es wahrscheinlich egal. Wenn Sie die Präzision verlieren, wird die Zahl immer kleiner und nicht größer sein. – Armstrongest

1

Sie sollten nicht (int) verwenden, um ganzzahlige Werte zu vermeiden. Verwenden Sie eine parametrisierte Abfrage und legen Sie den Typ Ihrer Eingabe auf 'int' fest. Ein viel besserer Weg!

für ein Beispiel in mysql/php siehe: http://us.php.net/manual/en/mysqli.prepare.php

+1

Es ist nichts falsch daran, an ein 'int' zu übergeben.Während ich zustimme, dass parametrisierte Abfragen im Allgemeinen besser sind, liegt es nicht an der Sicherheit, sondern daran, dass es dich zwingt Aber wenn Sie sich selbst entziehen, ist es genauso sicher wie bei der Verwendung von parametrisierten Abfragen. Es ist absolut nichts falsch daran, einen Typ vor dem Anhängen an eine Abfrage zu erzwingen. Sicher, es gibt andere Möglichkeiten, dies zu tun, die Vorteile haben können, aber es ist nicht implizit falsch, wie von Ihrer Formulierung impliziert. – ircmaxell

+0

Wenn ich Parameter verwenden könnte, würde ich, aber ich kann nicht.Weil die Frage nicht speziell darüber war, hatte ich nicht das Bedürfnis zu disserttieren, warum ich nicht verwendet wurde mysqli/PDO. – Andrew

1

Es hängt davon ab, ob der Bruchteil genau binär dargestellt werden kann (siehe Fractions in binary). Zum Beispiel hat 0,5 eine exakte binäre Darstellung, aber 0,1 nicht. Wenn die Nummer keine genaue Darstellung aufweist, wird beim erneuten Drucken wahrscheinlich ein anderes Ergebnis angezeigt.