不知道为什么。 C#.Net 3.5
int a = 256 * 1024 * 1024;
int b = 8;
long c = b * a;
Console.WriteLine(c);//<-- result is -2147483648
这减去了哪里?
答案 0 :(得分:5)
这减去了哪里?
从整数溢出。请注意,您的代码等同于:
int a = 256 * 1024 * 1024;
int b = 8;
int tmp = b * a;
long c = tmp;
Console.WriteLine(c);
我已将赋值的乘法分离到long
变量以强调它们实际上是单独的运算 - 乘法是使用Int32
算术执行的,因为两个操作数都是{{1} - 之后将结果分配给Int32
这一事实无关紧要。
如果要在64位算术中执行乘法运算,则应将其中一个操作数强制转换为Int64
(即long
):
Int64
(你向int a = 256 * 1024 * 1024;
int b = 8;
long c = b * (long) a;
Console.WriteLine(c); // 2147483648
施放的操作数无关紧要 - 另一个操作数无论如何都会隐式转换为long
。)
答案 1 :(得分:1)
int
支持的最大值为2147483647
。预期结果2147483648
不适合此类型范围,因此发生溢出导致结果为负。
请注意,语句long c = b * a;
转换为以下两个步骤:
多个int
和b
的{{1}}值。由于整数溢出,a
结果为负。
将已经否定的结果转换为int
。
在乘以之前尝试转换为long
:
long
或声明long c = b * (long) a;
属于a
类型:
long
答案 2 :(得分:1)
int
是32位签名值类型,这意味着最后一位用于指定数字是正数还是负数。
int
的值范围从-2147483648
到2147483647
。这是
1000 0000 0000 0000 0000 0000 0000 0000
到
0111 1111 1111 1111 1111 1111 1111 1111
二进制。现在:
256 * 1024 * 1024
等于268435456
或
0001 0000 0000 0000 0000 0000 0000 0000
二进制文件。
268435456 * 8
等于2147483648
或
1000 0000 0000 0000 0000 0000 0000 0000
。
由于该值仍为int
,因此会循环回到最大负数字,因为如上所述,最后一位用于指定数字是正数还是负数。因此,2147483648
变为-2147483648
答案 3 :(得分:1)
正如其他人所说,你应该将表达式中的一个操作数作为long
来产生long
,但在你的情况下,所有操作数都是int
,因此,{{1返回。
你应该将其中一个投射到长:
int
分开时也是如此:
int a = 256 * 1024 * 1024;
int b = 8;
long c = (long)b * a;
所以将一个操作数强制转换为结果类型:
int a=1, b=2;
float c = a / b; //results in 0
BTW,还有用于检查算术溢出的C#指令:int a=1, b=2;
float c = (float)a / b; //results in 0.5
关键字
checked
答案 4 :(得分:0)
它将结果转换为long而不是操作,如果其中一个操作数很长就可以了。这很好用:
long a = 256L * 1024L * 1024L;
int b = 8;
long c = b * a;
Console.WriteLine(c);
就像这样:
int a = 256 * 1024 * 1024;
long b = 8L;
long c = b * a;
Console.WriteLine(c);
和这个(两个中只有一个需要投射,但我两个都要清楚):
int a = 256 * 1024 * 1024;
int b = 8;
long c = (long)b * (long)a;
Console.WriteLine(c);
答案 5 :(得分:0)
因为b * a在分配给long数据类型变量之前已经是溢出的整数。