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

时间:2010-06-08 20:32:37

标签: c# math int

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

我做IF (X * Y > Z)这样的事情时遇到了这个问题,其中Int32都是XYX * Y足够大,您可以从Int64获得虚假价值。

为什么会如此以及如何解决这个问题?除了将所有内容都转换为{{1}}。

6 个答案:

答案 0 :(得分:26)

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

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

FFFFFFFF * FFFFFFFF = FFFFFFFE00000001

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

答案 1 :(得分:19)

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

您可以使用checked and unchecked keywords来控制该行为。

答案 2 :(得分:8)

有趣的是,无论你使用什么基础,这都有效:

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

答案 3 :(得分:6)

你必须要求它:

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

答案 4 :(得分:6)

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

答案 5 :(得分:2)

Int32.MaxValue(使用给定的值here)是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。

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

你得到: 00111 01110 + 11100 = 100001

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

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