Modulo - double

I

ip7

Mitglied
Hallo,
habe gelesen, daß Modulo für double Werte in Java definiert ist - im Gegensatz zu C++? In einem Test sehe ich, daß der Modulo-Operator unzuverlässig und nicht performant genug ist. Z.B. System.out.println("TEST "+ round(19.2%1.2,2)); hat das Ergebnis 0.0, aber System.out.println("TEST "+ round(20.4%1.2,2)); ergibt 1.2?
Man kann das wohl nicht so einfach einsetzen?
Danke.
 
kneitzel

kneitzel

Top Contributor
Das liegt einfach an der Ungenauigkeit. Der Rest bei der zweiten Berechnung ist dann halt 1.1999999999999993. Damit bist Du halt sehr nah an der 1.2. Die Ungenauigkeit war bei der 19.2 geringer, so dass da 0.0 rausgekommen ist.

Du kannst viele Dezimalwerte halt nicht genau im dualen System darstellen. Du hast kleine Abweichungen und diese machen sich hier jetzt sehr bemerkbar.
 
kneitzel

kneitzel

Top Contributor
Um es noch einmal die Problematik zu verdeutlichen:
Dezimalwerte lassen sich oft nicht exakt im binären System abbilden. Dadurch kommen dann zwangsläufig Abweichungen.

Man hat halt nur eine begrenzte Menge Bits und man muss halt an die Zahl ran kommen mit einer Reiche von 2 hoch -x.
1.2 = 1 * 2^0 + 0 * 2^-1 + 0 * 2^-2 + 1 * 2^-3 + .... = 1.001......

zeigt dies für float - also mit geringerer Genauigkeit. Aber die Problematik kann man da auch schon sehr gut erkennen:
- Wenn Du da 1.2 eingibst, dann zeigt er Dir, dass er in Wirklichkeit keinen Wert von 1.2 speichert sondern er statt dessen mit 1.2000000476837158203125 rechnet.
- Bei 20.4 hat er bei float in Wirklichkeit einen Wert von 20.3999996185302734375 gespeichert.

Du erkennst die klare Abweichung an diesen Beispielen. Bei double wird die Genauigkeit höher, aber so Abweichungen bleiben. Und wenn Du dann damit rechnest, dann vervielfältigt sich so ein Fehler natürlich.

Oder eine andere Visualisierung:
Java:
        double summe = 0.0;
        for (int i = 1; i <= 1000; i++) {
            summe += 1.2;
            System.out.println(i + " -> " + summe);
        }

Schon bei 9 Additionen ist eine Abweichung zu erkennen: 9 -> 10.799999999999999
 
B

Barista

Top Contributor
Für die Probleme mit der Genauigkeit und dem dualen Zahlensystem (schon einige Gleitkomma-Literale können nicht *-Periode in double umgesetzt werden) empfehle ich die Nutzung von BigDecimal.
Ist eben etwas langsamer.
 
I

ip7

Mitglied
Danke fürs Erklären. Ich verstehe nun wieso das so ist. Das mit BigDecimal werde ich morgen testen.
 
H

httpdigest

Top Contributor
Als Anmerkung die hier besonders fuer Anfaenger wichtig ist: Wird man in den 99,9% der Faelle nicht bemerken das es langsamer ist.
Und in 99,99999% der Fälle braucht man sowieso keine Fliesskomma-Datentypen, sondern Festkommawerte (sowieso immer nur 1 oder 2 Stellen nach dem Komma) bzw. Ganzzahltypen wie in diesem Fall int, reichen vollkommen aus.
Zur Ausgabe kann man dann noch / 10 oder / 100 teilen, meinetwegen mit BigDecimal.
 
kneitzel

kneitzel

Top Contributor
Nur am Rand-Rande: Jeder weiß, was mit Modulo gemeint ist, beim Wort "Remainder" aber nicht.
Ja, ganz offensichtlich wissen das einige nicht, incl. Dir.

a) Man sollte die Begrifflichkeiten doch bitte richtig verwenden. Und der Hinweis zur JLS ist ja bereits gefallen.
b) Feine Unterschiede gibt es - siehe z.B. https://stackoverflow.com/questions/13683563/whats-the-difference-between-mod-and-remainder

Edit: @mrBrown mogelt oder mein Browser aktualisiert nicht richtig ... ich poste und dann kommt, dass er schon vor 5 min gepostet hat? Sauerei ... Das ist bestimmt eine Form des Mobbing ... :p
 
J

Jw456

Bekanntes Mitglied
Negative Ganzzahl natürlich auch. Da kann es mathematisch auch einen Rest geben.
In der Mathematik gibst es keinen Rest bei flieskomma zahlen.

Duale komma zahlen können ja nicht i endlich aufgelöst werden die 64 bit sind bei double auch mal zuende.
 
kneitzel

kneitzel

Top Contributor
Der Stackoverflow Beitrag, den ich verlinkt habe, führt die Unterschiede ja auch aus. Aber evtl. war es nicht deutlich genug.

Folgenden Blog-Eintrag habe ich gefunden, der es auch erklärt:

Falsch, 10 % -3 gibt -2.
10 remainder -3 gibt 1
Das ist so nicht ganz durchdacht. % ist ja der remainder (in Java aber auch in C98 so ich mich jetzt nicht irre). Da hättest du besser mod statt % geschrieben.

Da Modulo und Remainder bei positiven Zahlen das gleiche Ergebnis liefern, wird dies gerne durcheinander geworfen. Aber das ist nicht korrekt, denn sobald die Vorzeichen unterschiedlich sind, kommen unterschiedliche Ergebnisse raus.

Die Berechnung beruht ja etwas wie:
a % b
-> es wird erst a/b gerechnet. Das Ergebnis ist dann aber nur ein Ganzwert -> Hier kommen wir dann gleich drauf zurück.
-> dann wird a - Ergebnis * b gerechnet.

Also bei dem Beispiel 10 / -3 = -3,33333333....
Hier können wir nun Math.floor oder Math.trunc/umwandlung in int nutzen. Also die -4 oder eine -3

Bei Remainder wird das trunc genommen. Daher ist es -3 und es kommt die 1.
Bei Modulo wird das floor genommen und damit die -4 und 10 - (-4)*(-3) = -2

Das wäre dann auch noch einmal die Erläuterung.

Und das dies so bei Modulo ist, kann man ansonsten auch nachvollziehen z.B. auf Wikipedia:
Das entscheidende ist dabei:
Die Gaußklammer {\displaystyle \lfloor \cdot \rfloor }
\lfloor \cdot \rfloor
bezeichnet die größte ganze Zahl, die nicht größer als die Zahl in der Gaußklammer ist
und somit schlicht das Math.floor.
 
J

Jw456

Bekanntes Mitglied
Mathematisch ist das falsch 10 : - 3 ist - 3 Rest 1

Wie es java dual rechnet wurde schon erklärt
 
Zuletzt bearbeitet:
kneitzel

kneitzel

Top Contributor
Mathematisch ist das falsch 10 : - 3 ist - 3 Rest 1
Ja, das ist der Rest, auf Englisch Remainder.

Aber das ist nicht das Modulo Ergebnis. Denn da hättest Du anders vorgehen müssen:

a mod m ist definiert als: a - | a/m | * m (mit | .. | den Gaußklammern. )

Also ist a/m bei 10/-3 die -3.3333... Die größte ganze Zahl, die kleiner als -3.3333 ist, ist -4. Also ist 10 mod -3 = 10 - (-4*-3) = 10 - 12 = -2

Man kann mich im Java Umfeld gerne belächeln, weil ich die JLS gerne heran ziehe für klare und (mehr oder weniger) saubere Definitionen.
Aber in der Mathematik darauf zu verzichten ist einfach nur fatal und man disqualifiziert sich. Da ist dann auch jede weitere Diskussion zwecklos, denn jede Mathematische Diskussion beruht eben auf den Definitionen.

Prinzipiell ist es möglich, seine eigenen Definitionen zu machen.

Aber macht das Sinn? Probieren wir es einfach mal aus:
Multiplikation ist bei mir -
Division ist bei mir *
Addition mache ich per /

<hier jetzt noch viel Text ... ich will ja nicht nur eine einfache Rechnung, sondern ich erläutere etwas, was ich zeigen will und so ... und nun kommt die Beweisführung in der folgenden Form>

3 - 4 / 2 * 4 = 12,5

Und das ist natürlich Richtig: 3 - 4 = 12 und 2 * 4 = 0,5 und 12 / 0,5 = 12,5
Findest Du verwirrend? Na sowas aber auch ... Also sollten wir Operatoren so belassen, wie sie sind und die nicht wild tauschen :)
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
P große double Zahlen und modulo Allgemeine Java-Themen 8
P Best Practice Wieso funktioniert der Modulo - Operator nicht? Allgemeine Java-Themen 2
T Modulo-Operator versagt bei zu großen Zahlen? Allgemeine Java-Themen 14
A Was berechnet Modulo denn da? Allgemeine Java-Themen 5
C Brauche Hilfe mit Modulo Strategie Allgemeine Java-Themen 2
R Modulo mit negativen Zahlen Allgemeine Java-Themen 8
B "Verschlüsselung" mit Passwort (XOR bzw. Modulo) Allgemeine Java-Themen 7
hdi Wahrscheinlichkeitsfrage bei hashCode() mit modulo Allgemeine Java-Themen 7
I Problem mit Modulo Allgemeine Java-Themen 14
scitex Eclipse Fehlermeldung - The constructor Double(double) is deprecated Allgemeine Java-Themen 8
O Variablen Addition von Double-Werten ergibt seltsame 0.9999999 Zahlen Allgemeine Java-Themen 2
B Long in einen Double umwandeln und im Label anzeigen Allgemeine Java-Themen 7
VfL_Freak Double mit zwei festen NK-Stellen ausgeben Allgemeine Java-Themen 9
B List<Integer> ist List<Double> ? Allgemeine Java-Themen 6
SkyScreamer Variablen Int umwande in Double/ 1 Miner = 5 Cookies/s Allgemeine Java-Themen 2
T Teile eines Double-Wertes verändern Allgemeine Java-Themen 2
T Double salted bcrypt Allgemeine Java-Themen 0
A Zahl abgerundet obwohl Double Allgemeine Java-Themen 9
R jTable, nur Werte zwischen 2 Double values ausgeben Allgemeine Java-Themen 3
Y String to Double ohne ParseDouble Allgemeine Java-Themen 11
D Double aus String auslesen Allgemeine Java-Themen 8
M double Array Allgemeine Java-Themen 8
P Wird double und float auf jedem Computer gleich berechnet? Allgemeine Java-Themen 10
C String in double[][] konvertieren! Allgemeine Java-Themen 5
M Cast double[]-->Object[] oder Vector<double[]> Allgemeine Java-Themen 3
Zettelkasten Double --> Integer Allgemeine Java-Themen 4
M float, double, BigDecimal Allgemeine Java-Themen 5
S Variablen Prüfen ob Number vom Typ Integer, Float, Double, ... ist Allgemeine Java-Themen 2
J String mit "," in Double Wert konvertieren Allgemeine Java-Themen 7
R Eclipse Verschiedene Ergebnisse bei Berechnung eines double-Werts Allgemeine Java-Themen 5
B Variablen Bug of Float. & Double.MIN_VALUE! Allgemeine Java-Themen 4
T ArrayList<double[]> persitent anlegen Allgemeine Java-Themen 7
K double Zufallszahl Allgemeine Java-Themen 6
S String in Double - letztes Zeichen fehlt Allgemeine Java-Themen 4
T int <-> integer, double <-> Double... Allgemeine Java-Themen 2
J Umstellung von double auf BigDecimal Allgemeine Java-Themen 5
H2SO3- String 1.000,00 in double umwandeln Allgemeine Java-Themen 12
S Double-Checked Locking Allgemeine Java-Themen 4
I 2D-Grafik Polygon mit Double Werten zeichnen Allgemeine Java-Themen 4
M FIFO Queue: bytes in, float/double/etc out Allgemeine Java-Themen 5
H double dispatch und equals(Object) Allgemeine Java-Themen 6
vandread Float/Double probleme bei der Multiplikation?! Allgemeine Java-Themen 3
J Casting Problem Object, Double und String Allgemeine Java-Themen 3
F double auf 2 Nachkommastellen runden Allgemeine Java-Themen 9
D Double to Integer - ist das möglich? Allgemeine Java-Themen 3
T Object auf Double, Int, String testen Allgemeine Java-Themen 5
H2SO3- großen double in string mit e umwandeln Allgemeine Java-Themen 4
T Problem: Double als Geldbetrag - Rundungsfehler Allgemeine Java-Themen 5
G Double Wert über OutputStream verschicken Allgemeine Java-Themen 2
M größer als double? Allgemeine Java-Themen 4
N Double ohne Wissenschaftliche Schreibweiße Allgemeine Java-Themen 5
M Double Braces Notation um Collections zu initialisieren Allgemeine Java-Themen 9
R Eigene ArrayList vom Typ Short, Integer oder Double Allgemeine Java-Themen 4
R Double Werte aus byte[] auslesen Allgemeine Java-Themen 5
T XStream.toXML => double mit , anstelle . Allgemeine Java-Themen 3
G Fehler bei Array.getDouble mit Double[] als Argument! Allgemeine Java-Themen 6
A Problem bei Übergabe von Werten in ein double Array. Allgemeine Java-Themen 21
M Double immer mit 2 Kommastellen Allgemeine Java-Themen 3
G double in Date Allgemeine Java-Themen 5
reibi double-Wert auf 2 Stellen nach dem Komma abschneiden Allgemeine Java-Themen 6
G Genauigkeit von Double Allgemeine Java-Themen 2
F Double mit Streams aus Datei einlesen Allgemeine Java-Themen 3
V "double in Exponentialschreibweise" normal ausgebe Allgemeine Java-Themen 2
S List<Double> oder Double[] in double[] zu konvertieren Allgemeine Java-Themen 6
C casten vom Typ Object nach Double[][] Allgemeine Java-Themen 2
E int vs. float vs. double Allgemeine Java-Themen 7
T cast Object to Double[] Allgemeine Java-Themen 2
DEvent double von c nach Java Allgemeine Java-Themen 4
K Double-Zahl runden Allgemeine Java-Themen 4
J double 3.0 soll ohne Nachkommastelle ausgegeben werden Allgemeine Java-Themen 12
S Java Double addieren Allgemeine Java-Themen 3
A string zu double Allgemeine Java-Themen 3
T double to object Allgemeine Java-Themen 3
J Große Zahl (double) as text ausgeben? Allgemeine Java-Themen 2
G Verständnisproblem double und float Allgemeine Java-Themen 7
P String in double parsen Allgemeine Java-Themen 6
E double auf int runden, nicht abschneiden Allgemeine Java-Themen 2
G Double Zahl quadrieren Allgemeine Java-Themen 8
C double Zahlen mit drei NachkommaStellen in String umwandeln Allgemeine Java-Themen 2
T Nachkommastellen double Allgemeine Java-Themen 18
M double aufrunden Allgemeine Java-Themen 6
W Division mit float und double Allgemeine Java-Themen 2
D JTextfield für double werte Allgemeine Java-Themen 2
S Format von Double Allgemeine Java-Themen 9
F Umwandlungsproblem mit double Allgemeine Java-Themen 2
S Problem! Lösung mit Double buffering Allgemeine Java-Themen 3
T Vector <-> double Allgemeine Java-Themen 4
W float/double verhält sich seltsam Allgemeine Java-Themen 6
D Double: Grenzen und Darstellung Allgemeine Java-Themen 7
W String to Double (landesspezifisch) Allgemeine Java-Themen 14
T Fließkomma (double) richtig runden Allgemeine Java-Themen 7
P Class zu Integer, String, Double etc. Allgemeine Java-Themen 11
R Fehler in WindowsXP oder Java? - double in int konvertieren Allgemeine Java-Themen 10
E NumberFormatException bei cast auf double Allgemeine Java-Themen 5
D Wann ist das ergebnis einer Rechnung eine Double? Allgemeine Java-Themen 7
G Double Zahl auf 4 Stellen hinter Komma kuerzen Allgemeine Java-Themen 4
G warum operator || cannot be applied to int, double Allgemeine Java-Themen 11
A Probleme Umwandlung Ausdruck String in double Allgemeine Java-Themen 4
B Double-Wert aus einem HexString erstellen. Allgemeine Java-Themen 11
R Double Buffering zu langsam Allgemeine Java-Themen 11

Ähnliche Java Themen


Oben