Zurück   Flashforum > Flash > ActionScript > ActionScript 1

Antwort
 
LinkBack Themen-Optionen Ansicht
Alt 23-01-2006, 14:24   #1 (permalink)
Linksaußen
 
Benutzerbild von Fralle
 
Registriert seit: Jun 2003
Ort: Essen
Beiträge: 552
Rundungsfehler??

Sicher gab's schon einige Posts zu Rundungsfehlern, aber woher kommt denn sowas??
ActionScript:
  1. var a:Number = 1.2701;
  2. var b:Number = 1.2708;
  3. var c:Number = (a+b)*5000;
  4. var d:Number = (a*5000+b*5000);
  5. trace(c);
  6. trace(Math.round(c));
  7. trace(d);
  8. trace(Math.round(d));
xxxx.5 sollte doch immer AUFgerundet werden, oder nicht?
__________________
Der Ball ist rund
Fralle ist offline   Mit Zitat antworten
Alt 23-01-2006, 15:01   #2 (permalink)
Level up
 
Benutzerbild von Alois
 
Registriert seit: Jun 2001
Ort: Bocholt
Beiträge: 4.155
...nun das ist durchaus ein Rundungsfehler, allerdings einer für den Flash nix kann, um zu verstehen wie es zu diesem Fehler kommt ändere erst mal Deinen Code ein wenig:
ActionScript:
  1. var a:Number = 1.2701;
  2.       var b:Number = 1.2708;
  3.       var c:Number = (a+b)*5000;
  4.       var d:Number = (a*5000+b*5000);
  5.       trace(c);
  6.       trace(c-12704.5);
  7.       trace(Math.round(c));
  8.       trace(d);
  9.        trace(d-12704.5);
  10.       trace(Math.round(d));
...
Ausgabe:
Zitat:
12704.5
-1.81898940354586e-12
12704
12704.5
0
12705
also ist der Wert von c nicht 12704.5 sondern minimal weniger, wie das kommt, na das ist das Standardproblem von Fließkommazahlen am Computer, das ist halt so wurde z.B. hier schon mal ausführlich erklärt.

Gruß

Alois
__________________
-Spuckt mir auf den Stuhl, ich will im Grünen sitzen-
Alois ist offline   Mit Zitat antworten
Alt 23-01-2006, 15:40   #3 (permalink)
Linksaußen
 
Benutzerbild von Fralle
 
Registriert seit: Jun 2003
Ort: Essen
Beiträge: 552
ja, ich hatte auch schon diverse Rechenfehler-Threads gelesen, nur daß dies auch vorkommt, wenn ich nur einen Multiplikationsfaktor ausklammere hätte ich nicht gedacht!
__________________
Der Ball ist rund
Fralle ist offline   Mit Zitat antworten
Alt 23-01-2006, 15:48   #4 (permalink)
a.k.a maddin79
 
Benutzerbild von madflanderz
 
Registriert seit: Jul 2003
Ort: berlin f-hain
Beiträge: 1.693
was sollen die klammern damit zu tun haben? die bestimmen doch nur die reihenfolge der operationen, hat mit der maschinengenauigkeit deshlab auch nix zu tun.

gruß maddin
__________________
www.madflanderz.de

ø,¸¸,ø¤º°`°º¤ø,¸¸,ø¤º°` _ addicted to bass _ `°º¤ø,¸¸,ø¤º°`°º¤ø,¸¸,ø
madflanderz ist offline   Mit Zitat antworten
Alt 23-01-2006, 16:55   #5 (permalink)
Level up
 
Benutzerbild von Alois
 
Registriert seit: Jun 2001
Ort: Bocholt
Beiträge: 4.155
Natürlich haben die Klammern damit zu tun!!
Das System versucht natürlich den Fehler selbst zu verhindern, solange es nicht mit Fliesskommazahlen rechnen muss ist es ja auch kein Problem die Werte im Speicher zu halten, das ist allerdings vorbei, falls eine Fliesskommazahl mit der anderen addiert wird, die Berechnung findet intern natürlich binär statt, und Flisskommawerte müssen eventuell gerundet werden...
...wird die Fliesskommazahl allerdings direkt multipliziert, so kann der Fehler minimiert werden...
...im Beispiel:
ActionScript:
  1. var a:Number = 1.2701;
  2. trace("a-1.2701="+(a-1.2701));
  3. var b:Number = 1.2708;
  4. trace("b-1.2708="+(a-1.2708));
  5. trace("a+b-2.5409="+(a+b-2.5409));
  6. trace("a*5000-6350.5="+(a*5000-6350.5));
  7. trace("b*5000-6354="+(b*5000-6354));
__________________
-Spuckt mir auf den Stuhl, ich will im Grünen sitzen-

Geändert von Alois (23-01-2006 um 16:56 Uhr)
Alois ist offline   Mit Zitat antworten
Alt 07-02-2006, 11:41   #6 (permalink)
Linksaußen
 
Benutzerbild von Fralle
 
Registriert seit: Jun 2003
Ort: Essen
Beiträge: 552
Dieser SCHH...Rundungsfehler macht mich noch waaaaahnisinnig!!

wie kann es sein daß mir dieses Script:
Code:
won = -0.6
if ((won*10-Math.round(won*10)) == 0) {
	cent = won/Math.abs(won)*0.1;
} else {
	cent = won/Math.abs(won)*0.05;
}
trace(won+"  "+cent+"  "+(won*10-Math.round(won*10)));
dies hier ausgibt??? -->
Code:
-0.6  -0.05  -8.88178419700125e-16
oder: (var won in -1.4 ändern)
Code:
-1.4  -0.05  -1.77635683940025e-15
Wenn Flash wenigstens zuverlässig immer den Rundungsfehler machen würde, aber NEIN. Das Script hier taucht in einer Anwendung bei mir auf und produziert dort diesen Rundungsfehler. Stecke ich das Script aber in ein neues Dokument, dann rechnet Flash korrekt....


Vielleicht kennt jemand ja eine andere Lösung zu folgendem Problem:
je nach dem, ob die var won eine zweite Stelle nach dem Komma hat (immer eine Fünf, es sind €uro-Angaben) soll die var cent 0.05 betragen oder eben 0.1 (in Abhängigkeit vom Vorzeichen von won)

eigentlich funktioniert das Script oben. Leider kommen diese Fehler bei Werten von 0.6, 1.2, 1.4 vor....



Ich will eigentlich nur scha
__________________
Der Ball ist rund
Fralle ist offline   Mit Zitat antworten
Alt 08-02-2006, 23:19   #7 (permalink)
Level up
 
Benutzerbild von Alois
 
Registriert seit: Jun 2001
Ort: Bocholt
Beiträge: 4.155
Zitat:
Zitat von Fralle
... Das Script hier taucht in einer Anwendung bei mir auf und produziert dort diesen Rundungsfehler. Stecke ich das Script aber in ein neues Dokument, dann rechnet Flash korrekt....
tja, dann wirst Du den wert won=0.6 wohl in Deiner anderen Anwendung nicht direkt vorliegen, sondern irgendwie berechnet haben, und dann kommt es halt vorher bereits zu diesem Rundungsfehler an dem Flash nun überhaupt keine Schuld trifft .... flash rechnet so korrekt, wie es Rechner und Programmierer (naja scripter) zulassen. Naja, das wird ja im hier von mir verlinkten thread schon ausführlich erklärt.
In Deinem Fall scheint das Problem ja äusserst einfach abzufangen zu sein:
ActionScript:
  1. won = -0.6
  2. var won1=Math.round(won*10000)/1000
  3. won=won1/10;
  4. if ((won1-Math.round(won1)) == 0) {
  5.     cent = won/Math.abs(won)*0.1;
  6. } else {
  7.     cent = won/Math.abs(won)*0.05;
  8. }
  9. trace(won+"  "+cent+"  "+(won*10-Math.round(won*10)));
__________________
-Spuckt mir auf den Stuhl, ich will im Grünen sitzen-

Geändert von Alois (08-02-2006 um 23:21 Uhr)
Alois ist offline   Mit Zitat antworten
Alt 09-02-2006, 10:01   #8 (permalink)
Linksaußen
 
Benutzerbild von Fralle
 
Registriert seit: Jun 2003
Ort: Essen
Beiträge: 552
Du hast natürlich recht. Der Fehler steckt weiter oben im Programm. Die Variable won wird mir mit trace zwar als "0.6" ausgegeben, weicht in Wahrheit aber minimal davon ab.

Was heißt Flash trifft keine Schuld?? Ich gebe hier niemandem die Schuld!

Aber 6 durch 10 ist immer noch 0.6 und nicht 0.688178419700125e-16wrrf3545mrk4554!

Die Frage ist, wie soll ich damit umgehen??
Da es nie sicher ist, wo genau der Fehler auftritt, müßte man alle Rechenoperationen absichern. Denn hinterher danach zu suchen, ist natürlich sehr mühsam.
In meinem Beispiel habe ich die Variable won so korrigiert:
Code:
won = Math.round(won*100)/100;
Trotzdem macht mich das irgendwie nicht glücklich, denn wenn ich mir Wochen später so einen Code ansehe und dann tauchen da plötzlich solch scheinbar überflüssige Rechenoperationen auf, macht das die ganze Sache sehr unübersichtlich.
Am besten, man kommentiert solche "Korrigierungsschritte" immer mit einem Vermerk, damit klar ist, was da im Moment eigentlich gerechnet wird.
__________________
Der Ball ist rund

Geändert von Fralle (09-02-2006 um 10:03 Uhr)
Fralle ist offline   Mit Zitat antworten
Alt 10-02-2006, 12:06   #9 (permalink)
Level up
 
Benutzerbild von Alois
 
Registriert seit: Jun 2001
Ort: Bocholt
Beiträge: 4.155
...aus meinem link oben:
Zitat:
...dieses Problem ist nämlich in allen Programmiersprachen existent.
es erfordert einfach etwas mathematisch-technisches Verständnis, eine Fliesskommazahl die im Dezimalsystem 'glatt' endet (z.B. 0,1) kann im Hexadezimalsystem unendlich lang sein (0,199999...) um diese also völlig korrekt wiedergeben zu können müsste man unendlich viele Bit haben, es gibt zwar Korrekturroutinen im Prozessor, aber vollig verhindern lässt sich das hardwaremässig nicht (woher soll der Prozessor wissen, ob Du nicht doch nur 0,199999 meinst), deshalb hat halt der Programmierer beim Erstellen der Software auf sowas zu achten.
....also nochmal: flash kann nicht anders, genau so wenig wie C, Java oder sonst eine Programmierspache, weil es technisch einfach nicht möglich ist.
Der Einzige der im diesem System anders kann ist der Entwickler.... und das bist in diesem Fall Du...und Du als Entwickler solltest wissen, daß solche Korrekturen manchmal nötig sind, dann wunderst Du dich auch nicht über eine solche Codezeilen.
Und wenn Du unbedingt auf 30 Stellen hinter dem Komma genau rechnen musst (daß ist kann in der Physik durchaus mal vorkommen), dann kannst Du das auch mit dem Computer, allerdings nur wenn Du den Rechenfehler von vornherein mit in Dein Programm hineindenkst (sonst schiesst Du mit Deinem Satteliten den Pluto ab, statt ihn zu umkreisen).
__________________
-Spuckt mir auf den Stuhl, ich will im Grünen sitzen-
Alois ist offline   Mit Zitat antworten
Antwort

Lesezeichen

Themen-Optionen
Ansicht

Forumregeln
Es ist Ihnen nicht erlaubt, neue Themen zu verfassen.
Es ist Ihnen nicht erlaubt, auf Beiträge zu antworten.
Es ist Ihnen nicht erlaubt, Anhänge hochzuladen.
Es ist Ihnen nicht erlaubt, Ihre Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks sind an
Pingbacks sind an
Refbacks sind an



Alle Zeitangaben in WEZ +1. Es ist jetzt 03:36 Uhr.

Domains, Webhosting & Vserver von Host Europe
Unterstützt das Flashforum!
Adobe User Group


Copyright ©1999 – 2012 Marc Thiele