Variablenüberlauf

Java2206

Mitglied
Ich habe folgendes Video, wo um die 54. Minute das Phänomen Variablenüberlauf erklärt wird.


Demnach sollte Folgendes möglich sein:
Java:
public class VariablenUeberlauf {
 
  public static void main (String[] args) {
    
    byte b = 126;
    byte a = 1;
    
    System.out.println(b);
    
    b = b + a;
    
    System.out.println(b);
    
    b = b + a;
    
    System.out.println(b);
    
    b = b + a;
    
    }     
}

In meinem Java-Editor bekomme ich einen Error, dass die Typen inkompatibel sind ("error: incompatible types: possible lossy conversion from int to byte") und Eclipse weigert sich sogar den entsprechenden Quellcode auszuführen. Hier müsste ich die Zeilen ändern:
b = (byte) (b + a);

Dann bekomme ich das, was ich im Video sehe.
Rich (BB-Code):
126
127
-128
Hat sich inzwischen bei Java etwas getan, um einen Variablenüberlauf zu verhindern? Könnt ihr mir ganz kurz sagen, warum der Quellcode aus dem Video nicht mehr funktioniert?
 

Java2206

Mitglied
Das Video ist von 2016-2017 ;) Ich habe ein Beispiel mit int versucht und das klappt:

Java:
public class IntegerUeberlauf {

    public static void main (String[] args) {
        
        int i = 2147483647;
        
        System.out.println(i);
        
        i = i + 1;
        
        System.out.println(i); // -2147483648
    }
}

Warum ist + für byte-Werte nicht definiert!? Kann ich das irgendwo nachlesen?
 

Java2206

Mitglied
Ist eigentlich schade, dass das Problem mit dem Variablenüberlauf nicht schön bei byte-Werten auftaucht. Das wäre sehr viel eingängiger...
 

Meniskusschaden

Top Contributor
Warum ist + für byte-Werte nicht definiert!? Kann ich das irgendwo nachlesen?
Man kann in der JLS die Regeln nachlesen, nach denen konvertiert wird. Z. B. hier für zweistellige numerische Operatoren. Ich glaube aber nicht, dass dort irgendwo begründet wird, warum man sich so entschieden hat. Vermutlich weil die unterstützen Plattformen ohnehin mindestens 32Bit-Wortlängen haben.
 

mihe7

Top Contributor
Warum ist + für byte-Werte nicht definiert!? Kann ich das irgendwo nachlesen?
Nachlesen, dass es so ist, kannst Du das in der Java Language Specification (z. B. https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.6.2).

Warum? Die JVM kennt keine Integer-Arithmetik bzgl. byte. Jetzt kann man natürlich wieder nach dem Grund fragen. Hier könnte man spekulieren: erstens ist die Zahl der Opcodes beschränkt, zweitens dürfte es wenig Sinn machen, Rechenoperationen auf byte anzubieten, wenn die CPU diese sowieso in mind. 16-Bit breiten Registern abarbeitet.
 

mrBrown

Super-Moderator
Mitarbeiter
Man kann in der JLS die Regeln nachlesen, nach denen konvertiert wird. Z. B. hier für zweistellige numerische Operanden. Ich glaube aber nicht, dass dort irgendwo begründet wird, warum man sich so entschieden hat. Vermutlich weil die unterstützen Plattformen ohnehin mindestens 32Bit-Wortlängen haben.
Afaik spielte da mit rein, dass man einen riesigen Haufen weniger opcodes braucht, müssten immerhin 16 für je byte, short und char sein
 

Java2206

Mitglied
Danke! Gibt es eingängige Beispiele für Variablenüberlauf, die praxisnah sind und die man kennen sollte?

Das Beispiel aus dem Java-Video fand ich interessant (wenn es denn funktionieren würde): Man könnte jemandem leicht erklären, dass man ein Arbeitszeitkonto führt und hier byte-Werte speichert, wenn dann jemand zufällig 129 Stunden angesammelt hat, dann wäre sein Konto negativ, was man - ohne Fehlermeldung - bei Abrechnungen nicht (!) erkennen würde. Bei so einem Beispiel wird das Problem bei den Datentypen eingängig deutlich. Gibt es 'vergleichbare' Probleme, die man auf solche Alltagsfälle runterbrechen könnte?
 

mihe7

Top Contributor
Gibt es 'vergleichbare' Probleme, die man auf solche Alltagsfälle runterbrechen könnte?
Das Problem existiert auch außerhalb des Computers. So zeigten die analogen Kilometerzähler in Autos früher oft nur 5 Stellen vor dem Komma, deckten also den Bereich von 0 bis 99.999,9 km ab. Bei 100.000 km wurden also wieder bei 0 begonnen.

Uhrzeit- und Kalenderangaben bestehen nur aus Überläufen: der Wertebereich der Sekunden ist bei einer Uhr zwischen 0 und 59. Danach gibt es einen Überlauf und der Minutenzeiger zählt diese mit - allerdings auch nur in einem Wertebereich zwischen 0 und 59. Dann kommen die Stunden ins Spiel, dann die Tage usw.

Auch in der Programmierung kommen Überläufe nicht so selten vor, wie man vielleicht meinen möchte: beim Quadrieren/Multiplizieren geht das z. B. sehr schnell: 60.000 x 40.000 > 2^31
 
X

Xyz1

Gast
Afaik spielte da mit rein, dass man einen riesigen Haufen weniger opcodes braucht, müssten immerhin 16 für je byte, short und char sein
ja, das ist der Grund; auf den Prozessoren und Architekturen auf denen eine JVM läuft wird mit 16- oder 32- oder 64-bit hantiert.

Aber Du, @Java2206 , kannst das ja ganz einfach nachstellen, indem Du im Nachhinein auf byte castest. Das schneidet die vorangestellten Bits ab.

Und, jetzt klinge ich wie ein Banker, effektiv ist es dann eine byte -Addition, -Subtraktion usw.
 
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben