heute morgen zeigte sich folgende Smiley-Geschichte
::pc :eek::verzweifel::suspect:|:grampa:| :idea:
Dabei dauerte der Übergang von zu :idea: bei meinem Azubi kürzer als beim Admin, welcher bereits über Java schimpfte…
als mein Azubi das Erste mal über die Fließkommaarithmetik stolperte:
Da dachte ich mir, man könnte ja mal ein Art Rätsel machen und schauen wer auf die richtigen Ergebnisse kommt ohne Ausprobieren und Tante Google. Die Begründung zur Lösung habe ich zwar bereits verraten aber es ist dennoch bei weitem nicht jedem Geläufig.
a=.1f; b=.2f; c=a/b;
System.out.println("c-=b: "+(c-=b));
System.out.println("a+b: "+(a+b));
System.out.println("(a+b)*10%3: "+((a+b)*10%3));
System.out.println("(a+b)*100%3: "+((a+b)*100%3));
System.out.println("(int)(a+b)*10%3: "+((int)(a+b)*1000%3));
System.out.println("(c)*10%3: "+((c)*10%3));
System.out.println("==================================================");
a=.1; b=.2; c=a/b;
System.out.println("c-=b: "+(c-=b));
System.out.println("a+b: "+(a+b));
System.out.println("(a+b)*10%3: "+((a+b)*10%3));
System.out.println("(a+b)*100%3: "+((a+b)*100%3));
System.out.println("(int)(a+b)*10%3: "+((int)(a+b)*1000%3));
System.out.println("(c)*10%3: "+((c)*10%3));```
@Mods, ich hoffe ich bin im richtigen Forum gelandet...
Die Ergebnisse per Hand ausrechnen
Das fieße ist schon der Anfang,
denn
.1f wird durch das float erstmal ein eine IEEE754 mit 32 bit umgerechnet, was
00111101110011001100110011001101 (dezimal: 0.10000000149011612) ergibt.
Ohne das f würde die Zahl als 64bit IEE 754 so dargestellt:
0011111110111001100110011001100110011001100110011001100110011010 (dezimal: 0.1)
Gleiches passiert bei dem 0.2f, das ergibt
00111110010011001100110011001101 (dezimal 0.20000000298023224).
Korrekt wäre dagegen
0011111111001001100110011001100110011001100110011001100110011010 (dezimal 0.2)
Du führst also alle Berechnungen mit double-Genauigkeit durch, rechnest aber intern mit
a = 0.10000000149011612
und b = 0.20000000298023224
Siehe dazu auch den Vergleich hier:
a=.1f; b=.2f; c=a/b;
System.out.println(b);
System.out.println("c-=b: "+(c-=b));
System.out.println("a+b: "+(a+b));
System.out.println("(a+b)*10%3: "+((a+b)*10%3));
System.out.println("(a+b)*100%3: "+((a+b)*100%3));
System.out.println("(int)(a+b)*10%3: "+((int)(a+b)*1000%3));
System.out.println("(c)*10%3: "+((c)*10%3));
System.out.println("==================================================");
a=0.10000000149011612; b=0.20000000298023224; c=a/b;
System.out.println("c-=b: "+(c-=b));
System.out.println("a+b: "+(a+b));
System.out.println("(a+b)*10%3: "+((a+b)*10%3));
System.out.println("(a+b)*100%3: "+((a+b)*100%3));
System.out.println("(int)(a+b)*10%3: "+((int)(a+b)*1000%3));
System.out.println("(c)*10%3: "+((c)*10%3));
System.out.println("==================================================");
a=.1; b=.2; c=a/b;
System.out.println("c-=b: "+(c-=b));
System.out.println("a+b: "+(a+b));
System.out.println("(a+b)*10%3: "+((a+b)*10%3));
System.out.println("(a+b)*100%3: "+((a+b)*100%3));
System.out.println("(int)(a+b)*10%3: "+((int)(a+b)*1000%3));
System.out.println("(c)*10%3: "+((c)*10%3));```
Nettes Beispiel dafür, warum man auch bei einer high-Level Sprache durchaus über die PC-Interna bescheid wissen sollte :)
Gruß
fies ist vor allem so ein Wort/ so eine Schreibweise
Nettes Beispiel dafür, warum man auch bei einer high-Level Sprache durchaus über die PC-Interna bescheid wissen sollte
um nicht nur zu spammen:
der Aufbau von Zahltypen ist doch eher Wissen über die Java-Spezifikation, hoffentlich hardware-unabhängig,
das ist das Level von Java, ob man es nun kennt oder ohne auskommt