![]() |
1
14
对于32位数据类型,没有+2^31的表达式,因为最大的数字是2^31-1…了解更多关于 two's complement … |
![]() |
2
42
实际上,在C语言中,行为是未定义的。根据C99标准,_§7.20.6.1/2:
及其脚注:
|
![]() |
3
10
因为整数以二进制补码的形式存储在内存中,所以最小值的正值溢出返回负值。 也就是说(在.NET中,但仍然适用):
和
|
![]() |
4
8
显然,数学上,−2 三十一 是2 三十一 . 如果我们有32位来表示整数,我们最多可以表示2 三十二 数字。如果我们想要一个对称于0的表示,我们需要做一些决定。 在下面的问题中,我假设32位宽的数字。必须至少为0使用一个位模式。所以我们只剩下2个 三十二 -其余数字的位模式为1或更少。这个数字是奇数,所以我们可以用一个不完全对称于零的表示,或者用两个不同的表示来表示一个数字。
在二的补码表示中,不能表示二
三十一
. 实际上,如果您查看编译器的
这样做而不是
因为2147483648太大,无法放入
所以,为了回答你最初的问题,在一个二的补码表示中,最大负数的绝对值不能用这个编码表示。另外,从上面,要在二的补码表示中从一个负值得到一个正值,您需要取其一的补码,然后加1。所以,为了
你把原来的号码拿回来。 |
![]() |
5
3
这又回到了数字的存储方式。 负数是用二的补码来存储的。算法就像… 翻转所有位,然后加1。 使用8位数字作为例子… +0=0 00000000->11111111、11111111+1=10000000 (但由于位的限制,这变成了00000000)。 还有… -128[aka-(2^7)]等于-(-128) 10000000->0111111、0111111+1=10000000 希望这有帮助。 |
![]() |
6
3
两个补数的表示法中,最重要的一位是负数。0x8000000是1后跟31个零,前1代表-2^31而不是2^31。因此,无法表示2^31,因为最大的正数是0x7fffffff,它是0,后面是31,等于2^31-1。 因此,abs(0x8000000)在二者的补码中是未定义的,因为它太大了,因此机器会放弃并再次给予你0x8000000。通常至少。 |
![]() |
7
1
我想办法
|
![]() |
8
1
0x8000…存储为10000….(二进制)。这被称为两个补码,这意味着最高的位(左边的位)用于存储值的符号,负值存储在负二进制-1中。abs()函数现在检查符号位,查看它是否已设置并计算正值。
现在这又是一个负数,我们不想要它,原因是溢出,请尝试数字0x9000…是10010…
使用这个数字,溢出被右边的0位停止。 |
![]() |
9
0
因为它使用neg指令来执行这个操作。 在汇编语言编程的艺术书籍中,他们这样说。
资料来源: http://www.arl.wustl.edu/~lockwood/class/cs306/books/artofasm/Chapter_6/CH06-2.html#HEADING2-313 所以它会设置溢出标志并保持安静,这就是原因。 |
![]() |
Community wiki · C中有哪些耗时的操作? 1 年前 |
![]() |
Community wiki · 将所有处理器电源都投入到任务中 1 年前 |
![]() |
Community wiki · C++为C添加了什么?[已关闭] 1 年前 |
![]() |
Community wiki · 打印1到1000,不带循环或条件 1 年前 |