Warum kann ich einen Float nicht multiplizieren? [Duplikat]

7

Ich war ziemlich überrascht, warum ich versuchte, einen Float in C zu multiplizieren (mit GCC 3.2) und dass es nicht so lief, wie ich es erwartet hatte. Als Beispiel:

%Vor%

Anzeigen: 31.099998

Ich bin neugierig, wie Floats implementiert werden und warum es zu diesem unerwarteten Verhalten führt.

    
Dpp 13.06.2010, 05:00
quelle

6 Antworten

14

Als Erstes können Sie Floats multiplizieren. Das Problem, das Sie haben, ist nicht die Multiplikation selbst, sondern die ursprüngliche Nummer, die Sie verwendet haben. Die Multiplikation kann etwas an Genauigkeit verlieren, aber hier hat die ursprüngliche Zahl, die Sie multipliziert haben, mit der verlorenen Präzision begonnen.

Dies ist tatsächlich ein erwartetes Verhalten. float s werden mittels Binärdarstellung implementiert, was bedeutet, dass Dezimalwerte nicht genau dargestellt werden können.

Weitere Informationen finden Sie unter MSDN .

Sie können auch in die Beschreibung von float sehen hat 6-7 signifikante Ziffern Genauigkeit. In Ihrem Beispiel, wenn Sie 31.099998 auf 7 signifikante Ziffern runden, erhalten Sie 31.1 , so dass es hier immer noch wie erwartet funktioniert.

double type wäre natürlich genauer, hat aber einen Rundungsfehler aufgrund seiner binären Darstellung, während die Zahl, die Sie geschrieben haben, dezimal ist.

Wenn Sie vollständige Genauigkeit für Dezimalzahlen wünschen, sollten Sie einen Dezimaltyp verwenden. Dieser Typ existiert in Sprachen wie C #. Ссылка

Sie können auch die Darstellung rationaler Zahlen verwenden. Verwenden Sie zwei ganze Zahlen, die Ihnen vollständige Genauigkeit geben, solange Sie die Zahl als eine Division von zwei ganzen Zahlen darstellen können.

    
brickner 13.06.2010, 05:02
quelle
5

Dies funktioniert wie erwartet. Computer haben eine begrenzte Genauigkeit, da sie versuchen, Fließkommawerte aus Ganzzahlen zu berechnen. Dies führt zu Gleitkomma-Ungenauigkeiten.

Die Gleitkomma-Wikipedia -Seite geht viel detaillierter auf die Darstellung und die daraus resultierenden Genauigkeitsprobleme ein als ich hier :)

Interessante Real-World-Randnotiz: das ist teilweise, warum eine Menge Geld Berechnungen werden mit ganzen Zahlen (Cent) gemacht - lassen Sie nicht den Computer Geld mit mangelnder Präzision verlieren! Ich möchte meine $ 0,00001!

    
Stephen 13.06.2010 05:03
quelle
4

Die Zahl 3.11 kann nicht binär dargestellt werden. Der nächste Wert, den Sie mit 24 signifikanten Bits erhalten können, ist 11.0001110000101000111101, was dezimal zu 3.1099998950958251953125 führt.

Wenn Ihre Zahl 3.11 einen Geldbetrag darstellen soll, müssen Sie eine Dezimaldarstellung verwenden.

    
dan04 13.06.2010 05:08
quelle
2

In den Python-Communities sehen wir die Leute oft überrascht, also gibt es gut getestete und getestete FAQs und Tutorial-Abschnitte zu dem Thema (natürlich werden sie in den Text geschrieben) Begriffe von Python, nicht C, aber da Python-Delegaten Arithmetik auf das zugrunde liegende C und Hardware sowieso schwimmen, gelten alle Beschreibungen der float-Mechanik immer noch).

Es ist natürlich nicht der Fehler der Multiplikation - entferne die Anweisung wo du nb multiplizierst und du wirst trotzdem ähnliche Probleme sehen.

    
Alex Martelli 13.06.2010 05:04
quelle
1

Aus Wikipedia-Artikel :

  

Die Tatsache, dass Gleitkommazahlen   kann nicht alles real darstellen   Zahlen und dieser Fließkommawert   Operationen können nicht genau darstellen   wahre arithmetische Operationen, führt zu   viele überraschende Situationen. Das ist   bezogen auf die endliche Präzision mit   welche Computer im Allgemeinen repräsentieren   Zahlen.

    
qrdl 13.06.2010 05:04
quelle
0

Fließende Punkte sind nicht präzise, ​​weil sie Basis 2 (weil es binär ist: entweder 0 oder 1) anstelle von Basis 10 verwenden. Und die Umwandlung von Basis 2 in die Basis 10 führt, wie bereits erwähnt, zu Rundungspräzisionsproblemen. p>     

thyrgle 13.06.2010 05:06
quelle