Fehler im Zusammenhang mit Ceil()
Übersicht

sddsmhrBetreff: Fehler im Zusammenhang mit Ceil() |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Die Arithmetik ist bei BB3D eh unter aller Sau, diverse Rundungsfehler, Datentyp Single...
Teilweise mit absurden Konsequenzen, Beispiel 'Ceil': Code: [AUSKLAPPEN] fl#=0.15:i=100
Print Ceil(15.) ;output: '15.0' Print Ceil(fl#*Float(i)) ;output '16.0' (should be '15.0') Print "press key to quit" WaitKey() Grotesk. ![]() Nachtrag: Ich sehe gerade, dass sich der Fehler wohl auf die Multiplikation bei Gleitkommazahlen zurückführen lässt: Code: [AUSKLAPPEN] Print (0.15*100.-15.) ;output 9.53674e-007
Ein wenig Hintergrundwissen in puncto Numerik habe ich ja, und daher natürlich auch etwas Verständnis. ![]() |
||
- Zuletzt bearbeitet von sddsmhr am Sa, Jul 28, 2012 23:25, insgesamt einmal bearbeitet
![]() |
XeresModerator |
![]() Antworten mit Zitat ![]() |
---|---|---|
Alle Fließkommazahlen sind Fehlerbehaftet, weshalb man immer Ganzzahlen vorziehen sollte, wenn man es ganz genau braucht - ist auch in anderen Sprachen der Fall.
~VERSCHOBEN~ Nichts spezielles zu 3D hier. |
||
Win10 Prof.(x64)/Ubuntu 16.04|CPU 4x3Ghz (Intel i5-4590S)|RAM 8 GB|GeForce GTX 960
Wie man Fragen richtig stellt || "Es geht nicht" || Video-Tutorial: Sinus & Cosinus THERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld) |
![]() |
Noobody |
![]() Antworten mit Zitat ![]() |
---|---|---|
Die Arithmetik bei B3D folgt genau demselben IEEE754 Float-Standard wie alle anderen Programmiersprachen auch. Kann es gar nicht anders, denn die CPU hat das fest in Hardware implementiert ![]() Das Problem hier ist, dass 0.15 in binär nicht nicht in einer endlichen Anzahl Bits darstellbar ist, da es einen nichtabbrechenden Nachkommateil besitzt (0.0010011011011011011011011 .....). Somit kommt es zwangsweise zu Rechnungsfehlern, wenn ein Float oder ein Double zur Rechnung benutzt wird. Aus 0.15 wird dann nämlich 0.150000006 und aus 0.15*100 wird statt 15.0 ein 15.0000010. Ceil reagiert korrekt, indem es das auf 16 aufrundet. Das ist ein grundlegendes Problem in Computerarithmetik und nicht auf B3D beschränkt. |
||
Man is the best computer we can put aboard a spacecraft ... and the only one that can be mass produced with unskilled labor. -- Wernher von Braun |
sddsmhr |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ja, hatte oben schon nachgetragen, dass es an der Arithmetik liegen müsste, denn es ist ja bspw. schon 0.15 * 100.0 - 15.0 != 0.0
Mit der Implementierung einer Rechenarithmetik hatte ich mich nur am Rande mal im Zusammenhang mit dem Double-Double-Algorithmus beschäftigt, und daher kam mir das Problem auch irgendwie bekannt vor. Numerik und so ist aber schon wieder ein Weilchen her... Noobody hat Folgendes geschrieben: Das Problem hier ist, dass 0.15 in binär nicht nicht in einer endlichen Anzahl Bits darstellbar ist, da es einen nichtabbrechenden Nachkommateil besitzt (0.0010011011011011011011011 .....). Somit kommt es zwangsweise zu Rechnungsfehlern, wenn ein Float oder ein Double zur Rechnung benutzt wird. Aus 0.15 wird dann nämlich 0.150000006 und aus 0.15*100 wird statt 15.0 ein 15.0000010. Ceil reagiert korrekt, indem es das auf 16 aufrundet. Schoss mir auch gerade durch den Kopf, als ich noch einmal einen Multiplikationsalgorithmus im Netz nachvollziehen wollte. Dort wurde allerdings mit Potenzen von 2 bzw. deren Reziproken gerechnet, was natürlich in einer endlichen binären Dezimalentwicklung resultiert, was hier ja nicht der Fall ist.
|
||
![]() |
Nova |
![]() Antworten mit Zitat ![]() |
---|---|---|
Warum gibt es diese Fehler bei Kommazahlen? Ganz logisch begründbar: Man bräuchte unendlich Speicher für korrekte Werte, da man ja jede Zahl zwischen 0.000000000000000000 und 0.999999999999999999 darstellen können müsste, auch 0.123412341234123412. Diese Zahlen bräuchten bereits sehr viel mehr Bytes als die Dezimalzahlen in Blitz Basic (4 Byte, Float oder auch Single genannt). Irre langsam zum Rechnen und nicht sehr speicherschonend. Hinzu kommt: Das wären dann nur die Zahlen von 0.0 bis 1. ![]() Kernprobleme der Sache mal zusammengefasst: Dezimalzahlen können nicht exakt dargestellt werden. Deswegen nimmt man Annäherungen. Das heißt: 2.0 / 3.0 ergibt nicht 0.6666666666666.... sondern nur einen annähernden Wert, bei Blitz3D ist es 0.666667 BlitzMax kann mit Double (braucht 8 Byte Platz) schon einen genaueren Wert ausgeben: 0.66666666666666663 |
||
AMD Athlon II 4x3,1GHz, 8GB Ram DDR3, ATI Radeon HD 6870, Win 7 64bit |
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group