关于类型转换:C#错误中的乘法

Multiplication in C# error

当乘以一组int并将结果转换为long时,我会得到一个不同的答案,而不是当我乘以一组double并将结果转换为long时。如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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);

有人能告诉我为什么会这样吗?谢谢你


你有一个整数溢出,因为每当你乘以两个int,你就会得到int:到目前为止,这被解释为Int32

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

只比转换成Int64(long)。要更正实现,请声明所有变量最初都是long,例如

1
2
3
4
5
6
7
  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;


这可能是因为乘法的结果太大了,不能容纳在Int32中,但它可以容纳在一个双精度数中。

要更具体一点,请看十六进制中的x和y:

x = 0x000000007994b000
y = 0x000000057994b000

Int32只能保存较低的8个十六进制值。这就是为什么x是错误的号码。最低的8个十六进制值是正确的,但顶部被切断。


我做了一个简短的搜索,甚至在脚本上运行了一些测试,我发现了以下结果,在脚本格式中,我测试它为,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        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("");
        document.writeln("RESULT Y :" + y);

对于xy,结果都是23514624000,但是在c中,当你试图将所有整数相乘,结果就形成了一个整数,但我们也知道int.MAX = 2147483647比实际结果小,因此在分配给long x= a * b * c * d * ee * f * g * h * i * j * k * l * m;时,它会截断原始值,而在其他结果中,如果y不是您希望两个结果相同,可以使用以下代码,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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();

现在您将得到相同的结果,即23514624000