在下面的程序中,我将 i 初始化为 255 因此,在Binary中我们有:
0000 0000 1111 1111
那是在Hex:
0x 0 0 f f
所以根据Little-Endian布局: 首先存储低位字节 - 0xff 。
#include<cstdio>
int main()
{
int i=0x00ff; //I know 0xff works. Just tried to make it understable
char *cptr=(char *)&i;
if(*(cptr)==-127)
printf("Little-Endian");
else
printf("Big-Endian");
}
因此,当我在 cptr 中存储 i 的地址时,它应指向较低的字节(假设Little Endian,因为我的系统具有此功能)。< / p>
因此, * cptr 包含1111 1111
。这应该降到-127。因为 1 位用于符号位。
但是当我打印 * cptr 的值时,我得到 -1 ,为什么会这样呢?
请解释我哪里出错?
答案 0 :(得分:8)
您在哪里明白1111 1111
是-127
?显然,您假设“符号位”应该独立于其余位解释,即以+127
的二进制表示设置符号位应该将其转换为-127
,对吧?那么,以这种方式工作的表示确实存在:它被称为 Signed Magnitude 表示。但是,它在实践中几乎未被使用。大多数现代机器都使用 2's Complement 表示签名类型,这是完全不同的事情。
在补充机器上1111 1111
一直是-1
。 -127
将是1000 0001
。 1000 0000
是-128
,BTW。
除此之外,请记住char
类型不一定是签名的。如果您特别需要签名类型,则必须拼写出来:signed char
。
答案 1 :(得分:1)
1111 1111
是-1
,因为-1
是最大的负整数。请记住-1
在数学中超过-2
,因此为方便起见,二进制表示应具有相同的属性。因此1000 0001
代表-127
。
答案 2 :(得分:1)
有三种方法可以用二进制表示负数:有符号幅度,有补码和二进制补码。
有符号的幅度最容易理解:一位用于表示符号(0 = +,1 = - ),其他位表示值的大小。
在补码中,通过对相应的正数进行逐位求逆(切换所有位)来获得负值
在二进制补码中,正数和负数之间的转换方式不那么简单(翻转所有位,然后加1),但它具有一些特性,使其在计算机中特别有用。
因为计算机在二进制补码表示中运行良好,所以大多数计算机都使用它来表示整数。
出现问题的是你期望一个带符号的幅度表示(最高位设置,所以负值。所有其他位也设置,所以值= -127),但计算机使用二进制补码表示(所有bis set == -1)。