Fehler im Zusammenhang mit Ceil()

Übersicht BlitzBasic Beginners-Corner

Neue Antwort erstellen

 

sddsmhr

Betreff: Fehler im Zusammenhang mit Ceil()

BeitragSa, Jul 28, 2012 23:09
Antworten mit Zitat
Benutzer-Profile anzeigen
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. Shocked

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. Wink
  • Zuletzt bearbeitet von sddsmhr am Sa, Jul 28, 2012 23:25, insgesamt einmal bearbeitet

Xeres

Moderator

BeitragSa, Jul 28, 2012 23:22
Antworten mit Zitat
Benutzer-Profile anzeigen
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
T
HERE IS NO FAIR. THERE IS NO JUSTICE. THERE IS JUST ME. (Death, Discworld)

Noobody

BeitragSa, Jul 28, 2012 23:30
Antworten mit Zitat
Benutzer-Profile anzeigen
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 Razz

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

BeitragSa, Jul 28, 2012 23:37
Antworten mit Zitat
Benutzer-Profile anzeigen
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

BeitragSo, Jul 29, 2012 1:17
Antworten mit Zitat
Benutzer-Profile anzeigen
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. Wink

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

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group