将 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; 转换为以下两个步骤:

  1. 乘以 baint 值。由于整数溢出,int结果为负数。

  2. 将已经为负的结果转换为long

在相乘前尝试转换为 long

long c = b * (long) a;

或声明 a 类型为 long:

long a = 256L * 1024L * 1024L;

因为b * a已经是溢出整数,在赋值给long数据类型变量之前

int 是 32 位 signed 值类型,这意味着最后一位用于指定数字是正数还是负数。

int 值范围从 -21474836482147483647。这是

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
}