C 和位移位
C and bitwise shifts
我可能有一个关于 C 中的位移位的新问题。我想编写一个宏,它将 return unsigned char 的第 n 位。我最初的想法是左移 (7-n),将位移至 MSB 位置,然后右移 7,将位移至 LSB。这没有用,所以我开始在非宏观环境中进行测试。
所以这不起作用:
int main() {
unsigned char c=126,d,i;
for(i=0;i<8;++i){
d = (c<<(7-i)) >> 7;
printf("%d bit: %d\n",i,d);
}
return 0;
}
但这行得通:
int main() {
unsigned char c=126,d,i;
for(i=0;i<8;++i){
d = (c<<(7-i));
d >>= 7;
printf("%d bit: %d\n",i,d);
}
return 0;
}
我用 &mask 解决了原来的问题.. d=(c>>i)&1;
。但是,我仍然不明白为什么这两个不同...有什么想法吗?
与 unsigned char c=126
和 i==0
:
(c<<(7-i))
是一个 14 位值。
d = (c<<(7-i)) >> 7;
保留该 14 位值然后右移 7:保留信息。
d = (c<<(7-i)); d >>= 7;
在保存到 d
时将 14 位值截断为 8 位,然后右移:信息丢失。
获取位数 n 的正确方法是 val & (1u << n)
。对于宏,这将是:
#define BIT(val, n) ( (val) & (1u << (n)) )
如果您想要 1 或 0,则只需 (bool)BIT(0x80, 7);
等
虽然一般来说,请不要发明这样的宏,因为 val & (1u << n)
已经是最可读的规范形式。
这个u8 = val & (1u << 7);
远远优于u8 = BIT(val,7);
。
我可能有一个关于 C 中的位移位的新问题。我想编写一个宏,它将 return unsigned char 的第 n 位。我最初的想法是左移 (7-n),将位移至 MSB 位置,然后右移 7,将位移至 LSB。这没有用,所以我开始在非宏观环境中进行测试。
所以这不起作用:
int main() {
unsigned char c=126,d,i;
for(i=0;i<8;++i){
d = (c<<(7-i)) >> 7;
printf("%d bit: %d\n",i,d);
}
return 0;
}
但这行得通:
int main() {
unsigned char c=126,d,i;
for(i=0;i<8;++i){
d = (c<<(7-i));
d >>= 7;
printf("%d bit: %d\n",i,d);
}
return 0;
}
我用 &mask 解决了原来的问题.. d=(c>>i)&1;
。但是,我仍然不明白为什么这两个不同...有什么想法吗?
与 unsigned char c=126
和 i==0
:
(c<<(7-i))
是一个 14 位值。
d = (c<<(7-i)) >> 7;
保留该 14 位值然后右移 7:保留信息。
d = (c<<(7-i)); d >>= 7;
在保存到 d
时将 14 位值截断为 8 位,然后右移:信息丢失。
获取位数 n 的正确方法是 val & (1u << n)
。对于宏,这将是:
#define BIT(val, n) ( (val) & (1u << (n)) )
如果您想要 1 或 0,则只需 (bool)BIT(0x80, 7);
等
虽然一般来说,请不要发明这样的宏,因为 val & (1u << n)
已经是最可读的规范形式。
这个u8 = val & (1u << 7);
远远优于u8 = BIT(val,7);
。