2016-05-11 8 views
5
public class Test { 
     public static void main(String [] s) { 
      int x = 99999; 
      long y = 99999; 

      long res = x * x; 
      System.out.println("x^2 = " + res); 
      res = y * y; 
      System.out.println("y^2 = " + res); 
     } 
    } 



Output: 
    x^2 = 1409865409 
    y^2 = 9999800001 

Ich bin wirklich verwirrt, um die Ausgabe aus dem obigen Code-Segment zu sehen. Ich habe erwartet, die gleiche (richtige) Antwort zu bekommen, aber hier ist x^2 eigentlich falsch!Wirklich verwirrt durch Java-Datentyp in diesem speziellen Fall

+3

passt Sie laufen in einen Überlauf . Sobald "x" den Wert von "Integer.MAX_VALUE" erreicht hat, wird das Hinzufügen von "+ 1" zu "x" dazu führen, dass "x" zu "Integer.MIN_VALUE" wird. – SomeJavaGuy

+0

Check out http://stackoverflow.com/questions/1494862/multiplying-long-values ​​ – guiguiblitz

+1

Im ersten Fall multipliziert man zwei Ints und dann zu lange gegossen, in der zweiten multipliziert zwei lange –

Antwort

8

99999 * 99999 = 1001010100000010001101011011000001 binär (wenn Sie diese zählen, werden Sie feststellen, dass Sie 34 Bits benötigen, um diese Zahl im Speicher darzustellen).

intist 32-Bit lang, so zwei MSB s ausgeschnitten sind.

Das gibt Ihnen 01010100000010001101011011000001b = 1409865409 dezimal als Ergebnis.

Wenn Sie diesen Wert einer Länge von 64 Bit zuweisen, ändert sich das Ergebnis nicht. Die Multiplikation von zwei Ganzzahlen ergibt eine ganze Zahl.

3

Das ist, weil Sie integersx * x und das Ergebnis, dass vervielfachen integer sein (temporäre Variable, reden wir hier über das Ergebnis der x * x Betrieb nicht res = Teil). Da das Ergebnis größer als Integer.MAX_VALUE ist, erhalten Sie eine "seltsame" Nummer. Dann stellst du diese Zahl in die Variable long ein. Diese

ist, wie Sie dieses Problem zu beheben:

long res = 1l * x * x; 

Jetzt ist es 1l * x zu berechnen, und da erste Zahl long ist, wird es dies als long berechnen, dann multiplizieren mit x, und wieder, da zuerst Nummer ist long, das Ergebnis wird long sein, dann wird dieses Ergebnis in der Variablen res platziert.

In ähnlicher Weise können Sie beheben Problem mit dem Verlust Dezimalzahlen, wie für:

int a = 10; 
int b = 3; 
double d = a/b; 

Ergebnis für diese 3.0 sein wird. Aber, wenn Sie dies tun:

double d = (1d *a)/b; 
d = a/(b * 1d); 
d = (double) a/d; 

Beide werden 3.3333333333333335 (diese 5, auch das ist ein anderes Problem ...). Auch Casting zu Double für eine der Variablen funktioniert auch (danke @ Aconcagua).

+1

Warum mit einer Konstante multiplizieren - Sie einfach kann den ersten (oder zweiten ...) Operanden auf Long oder Double umwandeln. – Aconcagua

+0

das funktioniert, um ... weiß nicht, hat sich daran gewöhnt, ohne Grund ... –

+0

Sie führen eine überschüssige Operation (Multiplikation) auf diese Weise. Es sollte jedoch weg optimiert werden, aber Sie verlassen sich auf Optimierung, während Sie eine Alternative hatten, ohne sich auf etwas weiter verlassen zu müssen ... – Aconcagua

3

Da zuerst x * x in int Platz gemacht wird und nur dann wird das Ergebnis in eine long gelegt. Deshalb, auch wenn die long Variable groß genug ist, um das Ergebnis zu halten, bevor das Ergebnis in long setzen sie zunächst als int Produkt berechnet und das Ergebnis wird abgeschnitten, weil es nicht in int

Verwandte Themen