Largest Java Short (32767) plus 1 wird nicht negativ?

7

Kürzlich habe ich von der Komplement-Methode der beiden gelernt, die sowohl positive als auch negative Ganzzahlen im System der zweiten Basis darstellt. Ich habe dann versucht, dies in Aktion mit Java mit dem folgenden Funktionscode zu sehen:

%Vor%

Welche Ausgaben:

  

a: 2147483647

     

a + 1: -2147483648

     

b: 32767

     

b + 1: 32768

Was mich verwirrt, weil ich denken würde, dass b + 1, das als 011111111111111 in Binärform dargestellt wird, in 1000000000000000 oder dezimal in -32768 umgewandelt wird. Was ist los?

    
Brown Philip 08.03.2017, 21:50
quelle

5 Antworten

11

Obwohl b eine Abkürzung ist, ist der Ausdruck (b + 1) ein int. Der rechte Operand ist ein int, der linke Operand wird zu einem int hochgestuft, und der Ausdruck ist der promovierte Typ der Operanden.

Aus der Java-Sprachspezifikation 5.6.2 . Binäre numerische Werbung :

  

Die Erweiterung der Grundelementkonvertierung (§5.1.2) wird angewendet, um einen oder beide Operanden gemäß den folgenden Regeln zu konvertieren:

     
  • Wenn einer der Operanden vom Typ double ist, wird der andere in double konvertiert.
  •   
  • Andernfalls, wenn einer der Operanden vom Typ float ist, wird der andere in float konvertiert.
  •   
  • Andernfalls, wenn einer der Operanden vom Typ long ist, wird der andere in long konvertiert.
  •   
  • Ansonsten werden beide Operanden in den Typ int.
  • konvertiert   

Beachten Sie, dass diese letzte Heraufstufung auch dann auftritt, wenn beide -Operanden einen kurzen Typ haben. Sie können die Beförderung zu einem int mit (b + (short) 1) nicht vermeiden.

Von 15.18.2. Additive Operatoren (+ und -) für numerische Typen

  

Der Typ eines additiven Ausdrucks für numerische Operanden ist der promovierte Typ seiner Operanden.

    
Andy Thomas 08.03.2017, 21:53
quelle
3

1 ist ein int literal. Wenn Sie b+1 berechnen, fördern Sie tatsächlich b zu einem int und fügen dann 1 hinzu, was zu 32768 führt, was ein vollkommen legaler int -Wert ist. Wenn Sie es erneut in short umwandeln, sehen Sie den erwarteten Überlauf ( -32768 ):

%Vor%     
Mureinik 08.03.2017 21:53
quelle
3

doing + fördert automatisch short auf int . Tun Sie dies und Sie werden den Überlauf sehen.

%Vor%

Aus der Java-Sprachspezifikation 5.6.2 . Binäre numerische Werbung :

  

Die Erweiterung der Grundelementkonvertierung (§5.1.2) wird angewendet, um entweder oder zu konvertieren   Beide Operanden wie in den folgenden Regeln angegeben:

     
  • Wenn einer der Operanden vom Typ double ist, wird der andere in double konvertiert.
  •   
  • Andernfalls, wenn einer der Operanden vom Typ float ist, wird der andere konvertiert   schweben.
  •   
  • Andernfalls, wenn einer der Operanden vom Typ long ist, ist der andere   zu lang konvertiert.
  •   
  • Andernfalls werden beide Operanden in den Typ int konvertiert.
  •   

Beachten Sie die letzte Regel, also im Wesentlichen, dass bedeutet, dass, selbst wenn sie beide Shorts sind, sie zu int befördert werden, das kann nicht vermieden werden.

Sie könnten:

%Vor%

Und die Antwort wäre immer noch gültig.

    
Eduardo Dennis 08.03.2017 21:53
quelle
2

Wie andere bemerkt haben, fördert die Addition die Operanden auf int .

Beachten Sie, dass der Operator += das Casting automatisch auf short zurücksetzt:

%Vor%

b++; / ++b; würde das gleiche Ergebnis wie b += 1 ergeben.

    
Andy Turner 08.03.2017 21:58
quelle
2

Keine Verwirrung, versuchen Sie das:

%Vor%

Was bekommst du? Richtig, du bekommst:

  

error: Inkompatible Typen: mögliche verlustbehaftete Konvertierung von int in short       kurz c = b + 1;

Was passiert also an deiner Leitung? System.out.println("b+1: "+(b+1)); ?

Nun, b+1 ist zu groß für short , wie Sie richtig gesagt haben, aber hier fügen Sie einen int hinzu, was das Ergebnis ebenfalls zu int macht. Und 32768 ist ein gültiger int.

Wie bereits erwähnt, erhalten Sie, wenn Sie es explizit auf (short) downline, das, wonach Sie gefragt haben.

Auf der anderen Seite funktioniert das nicht für short c = b + 1; , da hier der deklarierte Typ eine Abkürzung ist, während der tatsächliche Typ ein int ist.

short c = (short) (b + 1); löst dieses "Problem"

    
Lichtbringer 08.03.2017 22:02
quelle

Tags und Links