为何无符号3位位域会将-7转换为1?
问题分析与解答
#include <stdio.h> struct test{ unsigned int a:3; }; int main (int argc, char *argv[]) { struct test b; b.a = -7; // implicit truncation to 1 return 0; }
首先纠正一个概念错误:4位补码中-7的二进制是1001,而非你说的1111(1111是4位补码的-1)。
关于赋值后得到1的原因,核心是C语言中有符号数转无符号位域的规则:
- 当把有符号整数赋值给无符号位域时,首先会将该有符号数转换为对应无符号类型的值,规则是对
2^N取模(N为目标无符号类型的总位数,比如32位unsigned int就是2^32)。对于-7来说,转换为unsigned int后的值是2^32 -7。 - 随后,无符号位域会截断保留最低的
n位(此处n=3),也就是对2^3(即8)取模。由于2^32是8的整数倍,2^32 -7除以8的余数为1,最终位域存储的值就是1。
更简化的理解:赋值给n位无符号位域时,结果等价于将原数直接对2^n取模。-7对8取模,计算得-7 = (-1)*8 +1,余数为1,因此最终结果为1。
你之前的思路错误在于误用了原码逻辑,而C语言中整数以补码形式处理,无符号转换的取模规则才是关键,并非直接截断原码或忽略最高位。
内容的提问来源于stack exchange,提问作者Narayan
相关产品推荐
相关产品推荐

