bin auf folgendes gestossen:
wenn ich bei einem int valuezur maximalen grösse 1 dazuzähle, swapt das ganze aufgrund der 2-er komplementdarstellung ja auf den kleinsten negativ wert um:
Java:
int myvalue =Integer.MAX_VALUE;System.out.println(myvalue);
myvalue +=1;System.out.println(myvalue);
Ausgabe ist dann:
2147483647
-2147483648
Versuche ich dann dass ganze mit dem Datentyp double passiert folgendes:
Ausgabe ist wieder:
1.7976931348623157E308
1.7976931348623157E308
kann mir das wer erklären, warum diese rechenoperation nicht ausgeführt wird?
Übrigens, wenn ich nicht addiere oder subtrahiere, sondern multipliziere (z.b. mit 1.1 oder 0.9) wird der wert entsprechend verringert, oder im falle der multiplikation mit 1.1 auf "Infinitiy" gesetzt.
Also ich weiß es nicht.
Ich rate jetzt mal, dass es ein Genauigkeitsfehler ist, da es bei einer addition ab einem wert von
Java:
myvalue +=Math.pow(10,291);
in Infinity umschlägt und vorher nicht.
Evtl. liegt hier ungefähr die Größe des Rundungsfehlers bei der Floatingpoint - Berechnung für die Nachkommastellen der Basis dieser Potenz? (1.7976931348623157E308)
Kann das evtl. jmd mit "einfachen Worten" erklären
Yo! Wenn man zu einer riesen Zahl einen Fliegensh*t dazuaddiert, passiert einfach nichts - was wenig verwundert, da doubles eben nur eine bestimmte Stellenanzahl haben.
Ja, es ist ein Rundungsfehler. Ein double ist aus 64 Bits aufgebaut. Ein Bit für das Vorzeichen, 11 Bits für den Exponenten und 52 Bits für die Mantisse. Die Mantisse bezeichned dabei eine Zahl, die zwischen 1 und 2 liegt. Diese Zahl wird mit Hilfe des Exponenten dann in den richtigen "Bereich" gebracht. Mit Bereich meine ich z.B. einen Bereich zwischen 0 und 0.00..001 oder den Bereich zwischen 1 und 10 oder den Bereich zwischen 10^6 und 10^7.
Die genaue Formel ist: (1 + Mantisse/2^52) * 2^(Exponent-1023)
Wenn jetzt irgendwas gerechnet wird, dann muss natürlich immer gerundet werden. Anders als bei Integer wird nicht strikt auf die nächst kleinste Zahl gerundet (absoluter Fehler), sondern auf die nächst beste Approximation, die double schafft (relativer Fehler). Bei einer Zahl mit 308 Nullen, wie aus deinem Beispiel, wird eine zuätzliche 1 schlichtweg abgerundet. Damit das auf infinity rundet, musst du einen orderntlichen Brocken mehr dazu addieren
Bei der Multiplikation mit 1.1 Berechnest du eigentlich Zahl + Zahl/10. D.h du addierst ungefähr 10^308+10^307 und dieser Summand fällt natürlich massiv ins Gewicht, was in infinity resultiert.
kannst dich ja mal an den fliegensch**s herantasten:
Java:
publicstaticvoidmain(String... _){double max =Double.MAX_VALUE;for(double d =1;;){// add 50% each time
d *=1.5;if(Double.isInfinite(max + d)){System.out.println(d);break;}}}