为什么Int32.MaxValue * Int32.MaxValue == 1?
我知道, Int32.MaxValue * Int32.MaxValue
将产生一个大于Int32
的数字; 但是,这句话不应该提出某种例外吗?
当我做一些像IF (X * Y > Z)
这样的东西都是Int32
时候,我碰到了这个。 X
和Y
足够大,你从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#中,这些溢出将默认发生。