2015-01-12 12 views
5

Wenn ich eine Menge von int multipliziere und das Ergebnis in eine lange umwandelere, bekomme ich eine andere Antwort, als wenn ich eine Menge von Doppelungen multipliziere und das Ergebnis in eine lange umwandele. zB:Multiplikation in C# -Fehler

int a = 5; 
int b = 5; 
int c = 7; 
int d = 6; 
int ee = 6; 
int f = 8; 
int g = 9; 
int h = 6; 
int i = 6; 
int j = 4; 
int k = 8; 
int l = 9; 
int m = 5; 
long x = a * b * c * d * ee * f * g * h * i * j * k * l * m; 

double aa = 5; 
double ab = 5; 
double ac = 7; 
double ad = 6; 
double aee = 6; 
double af = 8; 
double ag = 9; 
double ah = 6; 
double ai = 6; 
double aj = 4; 
double ak = 8; 
double al = 9; 
double am = 5; 
long y = (long)(aa * ab * ac * ad * aee * af * ag * ah * ai * aj * ak * al * am); 

Kann mir jemand sagen, warum das passiert? Danke

+2

weil '' '' long'' und double' bekommen 'sind verschiedene Dinge –

+2

Double und float __cannot__ eine beliebige Zahl mit 100% Genauigkeit halten, es sei denn, es ist eine Potenz von 2. Stattdessen halten sie nur __ approximations__ .. Deshalb haben wir Dezimal – TaW

+1

Ich empfehle Überlaufprüfungen in Ihren Projekteinstellungen (um mindestens für den Debug-Build). – CodesInChaos

Antwort

13

Sie haben eine Integer-Überlauf, da, wenn Sie zwei int multiplizieren Sie int haben: dies als Int32 interpretiert wird bisher

a * b * c * d * ee * f * g * h * i * j * k * l * m 

und nur als in Int64 umgewandelt (long). Um die Implementierung zu korrigieren, deklariere alle Variablen, die anfänglich long sind, z.

long a = 5; 
    long b = 5; // actually, not necessary, since a * b will be long, but safer 
    long c = 7; 
    ... 
    long m = 5; 

    long x = a * b * c * d * ee * f * g * h * i * j * k * l * m; 
+5

Es war nicht einmal nötig, sie alle "lang" zu machen. "Erzwinge die Berechnung" dazu: 'lang z = (lang) a * b * c * d * ee * f * g * h * i * j * k * l * m;' – ChrFin

+2

@ChrFin: du ' In diesem Fall, technisch gesehen, muss * nur das erste Argument vom Int64-Typ sein; Wenn man jedoch mit Integer-Überläufen konfrontiert wird, ist es sicherer zu sagen: "Ich muss mit 64-Bit-Darstellungen arbeiten" und alle Integer-Argumente in Int64 umwandeln. –

+0

@DmitryBychenko: Danke, ich dachte, es wäre so etwas. – Ka0s

5

Das ist wahrscheinlich, weil das Ergebnis Ihrer Multiplikation zu groß ist, um in einem Int32 zu halten - doch es kann in einem Doppel gehalten werden.

Um ein bisschen genauer Blick auf x und y in hexadezimal sein:

x = 0x000000007994b000
y = 0x000000057994b000

Ein Int32 können die unteren 8 Hex-Werte nur halten. Deshalb ist x die falsche Nummer. Die niedrigsten 8 Hex-Werte sind korrekt, aber die Spitze ist abgeschnitten.

2

Ich gebe ihm eine kurze Suche und einige Tests auch auf Skripte als gut geführt und ich fand die folgenden Ergebnisse, in Skriptformat ich es als Test,

<script> 
     var a = 5; 
     var b = 5; 
     var c = 7; 
     var d = 6; 
     var ee = 6; 
     var f = 8; 
     var g = 9; 
     var h = 6; 
     var i = 6; 
     var j = 4; 
     var k = 8; 
     var l = 9; 
     var m = 5; 
     var x = a * b * c * d * ee * f * g * h * i * j * k * l * m; 
     var y = eval(a * b * c * d * ee * f * g * h * i * j * k * l * m); 
     document.writeln("RESULT X : " + x); 
     document.write("<br>"); 
     document.writeln("RESULT Y : " + y); 
    </script> 

und das Ergebnis war 23514624000 für beide x und y, aber in C# wie Sie versuchen, alle Integer zu multiplizieren und im Ergebnis eine ganze Zahl gebildet wird, aber wir wissen auch, dass int.MAX = 2147483647 die dann weniger als actuall Ergebnis ist, So im Ergebnis beim Zuweisen long x= a * b * c * d * ee * f * g * h * i * j * k * l * m; schneidet es die ursprünglichen Werte ab, und in anderen re Sult ist es nicht, wenn Sie in beide gleiche Ergebnis möchten, können Sie folgenden Code verwenden,

int a = 5; 
int b = 5; 
int c = 7; 
int d = 6; 
int ee = 6; 
int f = 8; 
int g = 9; 
int h = 6; 
int i = 6; 
int j = 4; 
int k = 8; 
int l = 9; 
int m = 5; 
long x = (long)a * b * c * d * ee * f * g * h * i * j * k * l * m; 

double aa = 5; 
double ab = 5; 
double ac = 7; 
double ad = 6; 
double aee = 6; 
double af = 8; 
double ag = 9; 
double ah = 6; 
double ai = 6; 
double aj = 4; 
double ak = 8; 
double al = 9; 
double am = 5; 
long y = (long)(aa * ab * ac * ad * aee * af * ag * ah * ai * aj * ak * al * am); 
Console.WriteLine(x); 
Console.WriteLine(y); 
Console.ReadKey(); 

Jetzt werden Sie das gleiche Ergebnis dh