Arithmetic Operators (Arithmetische Operatoren)
Kurz: Operatoren für die vier Grundrechenarten plus Modulo (Rest einer Division) — +, -, *, /, %.
Genauer: Der Modulo-Operator (%) liefert den Rest einer Ganzzahldivision und wird häufig genutzt, um z. B. zu prüfen, ob eine Zahl gerade ist (zahl % 2 == 0). Bei der Division zweier Ganzzahlen wird das Ergebnis in vielen Sprachen ebenfalls auf eine Ganzzahl abgeschnitten (kein automatisches Runden) — ein häufiger Anfängerfehler, wenn eigentlich ein Dezimalergebnis erwartet wird.
Im Detail
7 + 3 # 10
7 - 3 # 4
7 * 3 # 21
7 / 3 # 2.333... (Python: "echte" Division)
7 // 3 # 2 (Python: Ganzzahldivision, explizit)
7 % 3 # 1 (Rest der Division)Viele Sprachen (z. B. Java, C) unterscheiden bei / selbst nach dem Datentyp: 7 / 3 ergibt bei zwei int-Operanden 2 (der Nachkommateil wird einfach abgeschnitten, nicht gerundet), während 7.0 / 3 als double-Division korrekt 2.333... liefert. Das ist eine der häufigsten stillen Fehlerquellen für Einsteiger, weil kein Fehler oder Warnung auftritt — das Ergebnis ist einfach nur falsch, wenn man eine Kommazahl erwartet hatte.
Modulo hat noch mehr praktische Anwendungen als nur die Gerade-/Ungerade-Prüfung:
index % array_laenge // "wrap-around": Index bleibt immer im gültigen Bereich (z. B. Ringpuffer)
sekunden % 60 // Umrechnung Sekunden -> Minuten:Sekunden
zahl % 10 // letzte Ziffer einer Zahl extrahierenBei negativen Zahlen verhält sich Modulo je nach Sprache unterschiedlich — in manchen Sprachen (Python) hat das Ergebnis immer dasselbe Vorzeichen wie der Divisor, in anderen (Java, C) dasselbe Vorzeichen wie der Dividend. -7 % 3 ergibt in Python 2, in Java -1. Wer mit negativen Zahlen modulo rechnet, sollte das für die verwendete Sprache explizit nachschlagen statt sich auf ein universelles Verhalten zu verlassen.
Arithmetische Operatoren folgen der bekannten Punkt-vor-Strich-Regel (siehe Operator-Priorität) — *, / und % binden stärker als + und -.
Integer-Overflow
Ganzzahl-Datentypen haben eine feste Bitbreite und damit einen begrenzten Wertebereich (siehe byte, long) — rechnet man über diese Grenze hinaus, “überläuft” der Wert und springt (je nach Sprache) auf den kleinstmöglichen Wert zurück, statt einen Fehler zu werfen:
// 32-Bit int, Maximalwert 2147483647
maxWert + 1 // ergibt -2147483648, NICHT 2147483648 - stiller Fehler!Manche Sprachen (Python) haben dieses Problem gar nicht, weil Ganzzahlen dort automatisch beliebig groß werden können; andere (Java, C, Rust im Release-Modus) lassen den Überlauf ohne Warnung durchlaufen, was zu einer der klassischsten, am schwersten zu findenden Fehlerklassen in älterer Software zählt — u. a. Ursache mehrerer bekannter Sicherheitslücken, weil ein überlaufener Wert z. B. eine Längenprüfung unbemerkt aushebeln kann.
Gleitkomma-Ungenauigkeit
Bei Dezimalzahlen (siehe Gleitkommazahl) führt die binäre Speicherung dazu, dass viele auf den ersten Blick “einfache” Dezimalwerte nicht exakt darstellbar sind:
0.1 + 0.2 # ergibt 0.30000000000000004, nicht exakt 0.3Das ist kein Bug einer bestimmten Sprache, sondern eine Eigenschaft des IEEE-754-Gleitkommaformats, das praktisch alle modernen Sprachen verwenden. Für Geldbeträge oder andere Werte, bei denen exakte Dezimalgenauigkeit zählt, verwendet man deshalb dedizierte Dezimaltypen (BigDecimal in Java, Decimal in Python/C#) statt normaler float/double-Werte.
Operator-Überladung
In manchen Sprachen (C++, Python, C#) lässt sich definieren, was +, - usw. für selbstdefinierte Typen bedeuten sollen (“Operator Overloading”) — z. B. damit zwei Vektor-Objekte mit v1 + v2 addiert werden können, statt eine Methode wie v1.addiere(v2) aufrufen zu müssen. Das kann Code intuitiver lesbar machen, wird aber bei missbräuchlicher Nutzung (z. B. + überladen, um etwas völlig Unerwartetes zu tun) schnell verwirrend — die meisten Style-Guides empfehlen, Operatoren nur so zu überladen, dass ihr Verhalten der mathematischen Intuition entspricht.
Siehe auch: Operatoren, Operator-Priorität