2017-01-10 6 views
0

Ich bin die 2 sehr große Zahl in Java-Multiplikation, aber der mehrfach Ausgang scheint wenig seltsam
-CodeMultipliziert große Anzahl in Java

long a = 2539586720l; 
long b = 77284752003l; 
a*=b; 
System.out.println(a); 
a=(long)1e12; 
b=(long)1e12; 
a*=b; 
System.out.println(a); 

Output:

-6642854965492867616 
2003764205206896640 

Im ersten Fall, warum das Ergebnis negativ ist, wenn es wegen Überlauf ist, wie kommt dann das Ergebnis der zweiten ist positiv? Bitte erläutern Sie dieses Verhalten? Code

Edit: 

Ich verwende mod=100000000009 Betrieb noch negativ es ist?

+0

Dies kann auf eine Kürzung zurückzuführen sein, da das Ergebnis nicht in einem 'long' gespeichert werden kann. Wenn 'lang' nicht genug ist. Versuchen Sie es mit 'BigInteger' –

+0

@ redflar3 das ist kein Problem, das Hauptproblem ist, warum' negative 'im ersten Fall während' positive 'auf zweiten Fall –

+1

lange halten kann (2^63-1, die 9e18 ist), wo als Ergebnis Ihrer ersten Multiplikation übersteigt 1e20. Dies führt zur Kürzung, daher ist das Ergebnis nicht korrekt. In ähnlicher Weise wird das zweite Ergebnis ebenfalls abgeschnitten, wie es 1e24 sein sollte. daher BigInteger verwenden –

Antwort

1

Ja. Es ist ein Überlaufproblem. Die lange Größe ist 8 Bytes und die range goes from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

Wenn Sie wirklich große Zahlen multiplizieren möchten. Verwenden BigInteger

import java.math.*; 

public static void main(String[] args){ 
    BigInteger bi1, bi2, bi3; 

    bi1 = new BigInteger("2539586720"); //or 1000000000000 
    bi2 = new BigInteger("77284752003"); 

    // multiply bi1 with bi2 and assign result to bi3 
    bi3 = bi1.multiply(bi2); 

    String str = bi1 + " * " + bi2 + " = " +bi3; 
    //Multiplication result is 2539586720 * 77284752003 = 196271329845312200160 
} 
+1

Importieren Sie 'java.math.BigInteger' nicht' * ' – Michael

2

Das Ergebnis, das Sie erhalten, ist typischerweise ein Überlaufproblem, für ein long: java ordnet 63 Bits für die Anzahl und die Most Significant Bit (MSB) für das Vorzeichen (0 für positive Werte und 1 für negative Werte) also 64 Bits insgesamt.

Damit wissen, gleich Long.MAX_VALUE + 1--9223372036854775808 weil Long.MAX_VALUE = 2^63 - 1 = 9223372036854775807 = 0x7fffffffffffffffL so, wenn wir 1, um es hinzuzufügen, wir 0x8000000000000000L = Long.MIN_VALUE = -2^63 = -9223372036854775808 erhalten. In diesem Fall wechselt das MSB von 0 zu 1, so dass das Ergebnis negativ ist, was Sie tatsächlich im ersten Anwendungsfall erhalten.

Wenn die MSB 1 eingestellt ist und Sie führen einen neuer Überlauf mit einem gewissen Berechnung, um es wieder zu 0 wechseln wird (weil wir nur die ersten 64 Bits halten), so wird das Ergebnis positiv sein, was eigentlich das, was Sie ist erhalten im zweiten Anwendungsfall.

Um dies zu vermeiden, müssen Sie BigInteger verwenden.

0

Wie pro JLS 15.17.1

Wenn eine Ganzzahl-Multiplikation überläuft, dann ist das Ergebnis die niederwertigen Bits des mathematischen Produkt wie in einigen ausreichend großen Zweierkomplement-Format dargestellt. Wenn ein Überlauf auftritt, kann daher das Vorzeichen des Ergebnisses nicht mit dem Vorzeichen des mathematischen Produkts der beiden Operandenwerte übereinstimmen.

Aus diesem Grund erhalten Sie negative Werte und haben keine Korrelation mit den eingegebenen Zahlen. Dies liegt daran, dass long in Java nur von -2^63 bis (2^63) -1 darstellen kann und Ihr Ergebnis größer ist.

Um dieses Problem zu vermeiden, sollten Sie bei der Arithmetik mit großen Zahlen immer BigInteger verwenden. Ein Beispielcode ist unten

BigInteger.valueOf(123L).multiply(BigInteger.valueOf(456L)); 
0

In Bezug auf das Verhalten sind beide Beispiele sind Überläufe. Die Tatsache, dass eine Antwort negativ ist, fügt keine besondere Bedeutung hinzu. Die erste Menge von Zahlen, die Sie multipliziert haben, führt zu einer langen Zahl, deren höchstwertiges Bit 1 ist, während die zweite Menge dies nicht tat.

Verwandte Themen