为什么Int32.MaxValue * Int32.MaxValue == 1?

我知道, Int32.MaxValue * Int32.MaxValue将产生一个大于Int32的数字; 但是,这句话不应该提出某种例外吗?

当我做一些像IF (X * Y > Z)这样的东西都是Int32时候,我碰到了这个。 XY足够大,你从X * Y得到一个虚假的值。

为什么会如此以及如何解决这个问题? 除了将所有内容都输入Int64之外

您已禁用项目中的溢出检查。 使用选中模式On会抛出exception。

因为int32将结果限制为32位。

所以,如果你在字节级别看一下数学。

 FFFFFFFF * FFFFFFFF = FFFFFFFE00000001 

如您所见,最低的4个字节= 1。

默认情况下,C#算法在未经检查的上下文中完成,这意味着值将翻转。

您可以使用选中和未选中的关键字来控制该行为。

有趣的是,无论您使用何种基础,这都有效:

 (n-1)*(n-1) mod nn^2 - 2n + 1 mod n 0 - 0 + 1 mod n 1 mod n 

你必须要求它:

 checked { int a = int.MaxValue; int b = int.MaxValue; int c = a * b; // kaboom } 

Int32.MaxValue(使用此处给出的值)是2,147,483,647。

在基数2中,即: 111 1111 1111 1111 1111 1111 1111 1111 … 2 ^ 31-1。 第一位是符号位。

如果你自己乘以它,你会得到: 11 1111 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000 0000 0000 0000 0001

回到“为什么它是1?”的原始问题,因为Integer.MaxValue是最大值,导致整数溢出。 结果被截断为最低31位,即0加1。

编辑:这是关于二进制乘法的教程 。 使用所有1的简单案例:111 * 111

你得到:00111 01110 + 11100 = 100001

您可以针对Int32.MaxValue的情况展开它。 为简洁起见,我将其缩短为3位数。

另外,正如另一个答案所说,在C#中,这些溢出将默认发生。