为什么两个正整数的乘积是负整数?

Why is the product of two positive integers a negative integer?

这学期我上了系统编程课。 为什么 50000*50000 会是负数? 我试图理解这个逻辑。 这是幻灯片的屏幕截图

slide image

32 位带符号整数的存储方式是第 0-30 位作为数字,第 31 位表示数字的符号。

这意味着可以表示的最大值是2,147,483,647(0-30的所有位都已设置,第31位为0表示正数)。

50,000 和 50,000 的乘积是 25,000,000,000 大于这个数字,这就是所谓的溢出。这意味着数据从其预期边界(底部 31 位)到符号位有 "overflowed"。

您现在设置了第 31 位,表示这是一个负数。要从它的二进制表示中找出一个负数,你需要取补码(翻转所有位),加一,然后在它前面加上一个负号。

当你取个的补码时要小心,你将自己限制在 32 位范围内......你不应该包括高于位 31 的位。

查看 signed number representations 了解更多信息。

这是因为在大多数编程语言中,整数数据类型具有固定大小。

这意味着每个整数值都有定义的最小值和最大值。

例如,在 C# 中,INT 最大值为 2147483647,MIN 为 -2147483648 在 PHP 32 位中是 2147483647 和 -2147483648 在 PHP 64 位中是 9223372036854775807 和 -9223372036854775808

当您尝试超过该值时会发生什么?只是计算机会使所谓的整数溢出,并且该值将循环回到最小值。

换句话说,在 C# 中 2147483647 + 1 = -2147483648(假设您使用整数数据类型,而不是长整数或浮点数)。这正是 50000 * 50000 发生的情况,它只是超过最大值并从下一个值开始循环。

确切的最小值和最大值取决于所使用的语言、构建代码的平台、代码所在的平台 运行 以及值的静态类型。

希望它能帮您解决所有问题!

示例程序伪代码

Print --> ("Size of int: " + (Integer.SIZE/8) + " bytes.");
int a=50000;
int b=50000;
Print --> (" Product of a and b " + a*b);   

Output :
Size of int: 4 bytes. 
Product of a and b:-1794967296

分析: 4字节= 4*8= 32bits.

由于signed int可以保存负值,一位用于符号(-或+),因此可用于数字范围的位数=31。 数字范围 = -(2^31) , 0 和 (2^31-1) [为0牺牲一个正数]

-2147483648, 0 和 2147483647

最大可能的正整数 = 2147483647(大于 1600000000,所以 40000*40000 可以) 实际产品50000*50000=2500000000(大于2147483647)

在实践中,许多可移植的 C 程序假设有符号整数溢出使用二进制补码算法可靠地回绕。 然而 C 标准说程序行为在溢出时是未定义的,并且在少数情况下 C 程序不能在一些现代实现上工作,因为它们的溢出没有像他们的作者预期的那样环绕。 http://www.gnu.org/software/autoconf/manual/autoconf-2.62/html_node/Integer-Overflow.html