我正在读一本书,上面写着:
“在像a * b这样的表达式中,如果a为-1并且b为1,则如果a和b均为整数,则值是预期的-1。但是,如果a为int且b为an unsigned,则此表达式的值取决于int在特定计算机上具有多少位。在我们的计算机上,该表达式的结果为4294967295。“
我的问题是:
为什么此表达式的值取决于int在特定计算机上具有多少位?以及他们如何获得4294967295的结果(在本文的结尾)。
对不起,我的英语不好。
答案 0 :(得分:1)
当将带符号和无符号相乘时,带符号的值将提升为无符号。升级规则规定将-1转换为最大可表示的值(this答案很好地说明了如何根据标准实际完成转换),该无符号值的所有位均已设置(带有2的补码,这是一个标识操作) ...)。
现在C ++标准(在这方面符合C标准)并未规定int必须具有多少位,所需要的只是unsigned int必须能够容纳从0到65535(十六进制)的整数值FFFF)(*)。为了满足要求,(无符号)int不能小于16位,但是也可以允许更多位,例如e。 G。在要测试的计算机上为32。现在猜测将所有这32位都设置为1(十六进制FFFFFFFF)产生的值...
(*)并非完全正确,实际上该标准还规定int不小于short且不大于long,但这在这里不相关...
答案 1 :(得分:1)
这是因为类型转换在算术运算之前应用于不同类型的操作数。例如,在cppreference.com上授予Arithmetic operators:
算术运算符
...积分转换应用于产生通用类型,如下 如下:
...,如果无符号操作数的转换等级大于或等于 有符号操作数的转换等级,有符号操作数为 转换为无符号操作数的类型。
因此,当您将(int)
与(unsigned int)
相乘时,整数值将在乘法完成之前立即转换为无符号整数。而且,如果您的体系结构使用2补码表示负值,则当{signed int为64位时,-1
表示为FFFFFFFFFFFFFF
,而当unsigned int为32位时,FFFFFFFF
表示为4294967295
。 >
您似乎拥有32位无符号整数,因为FFFFFFFF
与https://www.google.com/bookmarks/?output=xml
相同,即(2 ^ 32-1)
这就是原因。希望对您有所帮助。
答案 2 :(得分:0)
使用n位无符号整数,您可以编码0到2 ^ n-1(包括)之间的数字
4294967295
= 2 ^ 32-1
答案 3 :(得分:0)
在最简单的术语中:有符号变量将转换为无符号变量。当无符号变量降至零以下时,它将循环回到其最大值并从中减去而不是变为负数(它不能这样做)。在32位系统中,最大值为4294967296。如果从中减去1,则该数字将成为显示的数字。如果该机器上的位数不同,则最大值将有所不同,因此位数也将有所不同。