将 int 与 long 结果相乘 c#
Multiplying int with long result c#
不知道为什么。 C#.Net 3.5
int a = 256 * 1024 * 1024;
int b = 8;
long c = b * a;
Console.WriteLine(c);//<-- result is -2147483648
这个减去哪里来的?
Where does this minus from?
来自整数溢出。请注意,您的代码等效于:
int a = 256 * 1024 * 1024;
int b = 8;
int tmp = b * a;
long c = tmp;
Console.WriteLine(c);
我已经将乘法从对 long
变量的赋值中分离出来,以强调它们确实是独立的运算 - 乘法是使用 Int32
算术执行的,因为两个操作数都是 Int32
- 之后将结果分配给 Int64
的事实是无关紧要的。
如果要在 64 位算术中执行乘法,则应将其中一个操作数转换为 long
(即 Int64
):
int a = 256 * 1024 * 1024;
int b = 8;
long c = b * (long) a;
Console.WriteLine(c); // 2147483648
(将哪个操作数转换为 long
无关紧要 - 另一个操作数无论如何都会隐式转换为 long
。)
它将结果转换为 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);
int
支持的最大值为2147483647
。预期结果 2147483648
不适合此类型范围,因此发生溢出导致结果为负数。
请注意,语句 long c = b * a;
转换为以下两个步骤:
乘以 b
和 a
的 int
值。由于整数溢出,int
结果为负数。
将已经为负的结果转换为long
。
在相乘前尝试转换为 long
:
long c = b * (long) a;
或声明 a
类型为 long
:
long a = 256L * 1024L * 1024L;
因为b * a已经是溢出整数,在赋值给long数据类型变量之前
int
是 32 位 signed 值类型,这意味着最后一位用于指定数字是正数还是负数。
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
正如其他人所说,您应该将表达式中的操作数之一设为 long
以产生 long
,但在您的情况下,所有操作数都是 int
,因此,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
因此将其中一个操作数转换为结果类型:
int a=1, b=2;
float c = (float)a / b; //results in 0.5
顺便说一句,还有用于检查算术溢出的 C# 指令:checked
关键字
checked
{
int a = 256 * 1024 * 1024;
int b = 8;
long c = b * a; //this will throw System.OverflowException
}
不知道为什么。 C#.Net 3.5
int a = 256 * 1024 * 1024;
int b = 8;
long c = b * a;
Console.WriteLine(c);//<-- result is -2147483648
这个减去哪里来的?
Where does this minus from?
来自整数溢出。请注意,您的代码等效于:
int a = 256 * 1024 * 1024;
int b = 8;
int tmp = b * a;
long c = tmp;
Console.WriteLine(c);
我已经将乘法从对 long
变量的赋值中分离出来,以强调它们确实是独立的运算 - 乘法是使用 Int32
算术执行的,因为两个操作数都是 Int32
- 之后将结果分配给 Int64
的事实是无关紧要的。
如果要在 64 位算术中执行乘法,则应将其中一个操作数转换为 long
(即 Int64
):
int a = 256 * 1024 * 1024;
int b = 8;
long c = b * (long) a;
Console.WriteLine(c); // 2147483648
(将哪个操作数转换为 long
无关紧要 - 另一个操作数无论如何都会隐式转换为 long
。)
它将结果转换为 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);
int
支持的最大值为2147483647
。预期结果 2147483648
不适合此类型范围,因此发生溢出导致结果为负数。
请注意,语句 long c = b * a;
转换为以下两个步骤:
乘以
b
和a
的int
值。由于整数溢出,int
结果为负数。将已经为负的结果转换为
long
。
在相乘前尝试转换为 long
:
long c = b * (long) a;
或声明 a
类型为 long
:
long a = 256L * 1024L * 1024L;
因为b * a已经是溢出整数,在赋值给long数据类型变量之前
int
是 32 位 signed 值类型,这意味着最后一位用于指定数字是正数还是负数。
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
正如其他人所说,您应该将表达式中的操作数之一设为 long
以产生 long
,但在您的情况下,所有操作数都是 int
,因此,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
因此将其中一个操作数转换为结果类型:
int a=1, b=2;
float c = (float)a / b; //results in 0.5
顺便说一句,还有用于检查算术溢出的 C# 指令:checked
关键字
checked
{
int a = 256 * 1024 * 1024;
int b = 8;
long c = b * a; //this will throw System.OverflowException
}