我目前正在阅读C语言程序设计语言(K& R)的第2章并阅读有关按位操作的内容。
这是激起我好奇心的例子:
x = x & ~077
假设一个16位字长和32位长字型,我认为会发生077首先转换为:
0000 0000 0011 1111 (16 bit signed int).
然后补充:
1111 1111 1100 0000.
我的问题是x的不同可能类型接下来会发生什么?如果x是带符号的int,那么答案是微不足道的。但是,如果x是有符号长的,我假设〜077将成为:
1111 1111 1111 1111 1111 1111 1100 0000
以下2s补充以保留标志。这是对的吗?
另外,如果x是无符号长整数,则〜077将变为:
0000 0000 0000 0000 1111 1111 1100 0000
或者,将~077转换为签名的长第一个:
1111 1111 1111 1111 1111 1111 1100 0000
...之后它被转换为无符号长(不改变为位)?
任何帮助都可以帮助我澄清此操作是否始终仅将最后6位设置为零。
答案 0 :(得分:3)
无论您选择何种数据类型,~077
都会将最右边的6位设置为0
,将所有其他位设置为1
。
假设有16位int
和32位long
,则有4种情况:
案例1
unsigned int x = 077; // x = 0000 0000 0011 1111
x = ~x; // x = 1111 1111 1100 0000
unsigned long y = ~x; // y = 0000 0000 0000 0000 1111 1111 1100 0000
案例2
unsigned int x = 077; // x = 0000 0000 0011 1111
x = ~x; // x = 1111 1111 1100 0000
long y = ~x; // y = 0000 0000 0000 0000 1111 1111 1100 0000
案例3
int x = 077; // x = 0000 0000 0011 1111
x = ~x; // x = 1111 1111 1100 0000
unsigned long y = ~x; // y = 1111 1111 1111 1111 1111 1111 1100 0000
案例4
int x = 077; // x = 0000 0000 0011 1111
x = ~x; // x = 1111 1111 1100 0000
long y = ~x; // y = 1111 1111 1111 1111 1111 1111 1100 0000
请参阅代码here。这意味着当源为signed
时,符号扩展就完成了。当源为unsigned
时,符号位不会扩展,左侧位设置为0
。
答案 1 :(得分:2)
x = x & ~077 //~077=11111111111111111111111111000000(not in every case)
~077 is a constant evaluated at the complie time so its value will be casted according to the value of x at the compile time
所以AND操作总是会产生x的最后6位为0,其余的位将保持在AND操作之前的任何位。喜欢
//let x=256472--> Binary--> 0000 0000 0000 0011 1110 1001 1101 1000
x = x & ~077;
// now x = 0000 0000 0000 0011 1110 1001 1100 0000 Decimal--> 256448
因此,无论编译时数据类型如何,最后6位都会更改为0,其余位保持不变。在knr中,它写在那里The portable form
involves no extra cost, since ~077 is a constant expression that can be evaluated at compile time.