为什么是它的答案
-1, 2, -3 ? (especially -3 ??? how come)
struct b1 {
int a:1;
int b:3;
int c:4;
} ;
int main()
{
struct b1 c = {1,2,13};
printf("%d, %d, %d",c.a,c.b,c.c);
return 0;
}
在 VC++ 32 位编辑器上编译。非常感谢。
为什么是它的答案
-1, 2, -3 ? (especially -3 ??? how come)
struct b1 {
int a:1;
int b:3;
int c:4;
} ;
int main()
{
struct b1 c = {1,2,13};
printf("%d, %d, %d",c.a,c.b,c.c);
return 0;
}
在 VC++ 32 位编辑器上编译。非常感谢。
有符号整数以二进制补码表示。1 位二进制补码的范围是 -1 到 0。因为二进制补码的第一位表示它是负数,这就是您在那里所做的。
见这里: 符号扩展 1 位 2 的补码?
第三个数字也是如此,您已经溢出了 -8 到 7 的范围,这是一个 4 位有符号整数的范围。
你的意思是让所有这些int
->unsigned int
看这里的补码解释: http ://www.ele.uri.edu/courses/ele447/proj_pages/divid/twos.html
因为a
和c
是带符号位的有符号整数,因此它们是负数:
a: 1d = 1b (1 bit)
b: 2d = 010b (3 bits)
c: 13d = 1101b (4 bits)
有符号整数值存储在二进制补码中,最高位表示符号(1 表示“负数”)。a
因此,当您将位域值读取为有符号整数时,您会得到and的负值(c
符号扩展并从它们的二进制补码表示转换回来),但.2
b
要获得负二进制补码的绝对值,请减去 1 并将结果取反:
1101b
-0001b
======
1100b
1100b
倒转变成0011b
等于3d
。由于符号位是负数(无论如何在进行之前的计算之前你必须检查它),结果是-3d
.