我在C中看到了以下代码行here。
int mask = ~0;
我在C和C ++中打印了mask
的值。它始终打印-1
。
所以我确实有一些问题:
~0
分配给掩码变量?~0
的目的是什么?-1
代替~0
吗?答案 0 :(得分:79)
它是一种可移植的方法,可将所有二进制位整数设置为1位,而无需知道当前体系结构中的整数位数。
答案 1 :(得分:36)
C和C ++允许3种不同的有符号整数格式:符号量级,一个补码和两个补码
无论系统使用什么符号格式, ~0
都会生成全部位。所以它比<{1}}
您可以添加-1
后缀(即U
)以生成全部位模式可移植 1 。但是-1U
表示意图更清晰:反转值0中的所有位,而-1表示需要减去1的值,而不是其二进制表示
答案 2 :(得分:8)
在2的补充平台(假设)上给你-1,但是规则禁止直接写-1(只有整数0..255,一元!
,{{允许使用1}}和二进制~
,&
,^
,|
,+
和<<
。
答案 3 :(得分:5)
您正在研究编码挑战,对操作员和语言结构有许多限制,以执行给定的任务。
第一个问题是返回值-1 而不使用-
运算符。
在代表带有两个补码的负数的机器上,值-1
表示所有位设置为1
,因此~0
计算为-1
:
/*
* minusOne - return a value of -1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 2
* Rating: 1
*/
int minusOne(void) {
// ~0 = 111...111 = -1
return ~0;
}
文件中的其他问题并不总是正确实现。第二个问题,返回一个布尔值,表示一个int
值适合16位签名short
的事实有一个缺陷:
/*
* fitsShort - return 1 if x can be represented as a
* 16-bit, two's complement integer.
* Examples: fitsShort(33000) = 0, fitsShort(-32768) = 1
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 8
* Rating: 1
*/
int fitsShort(int x) {
/*
* after left shift 16 and right shift 16, the left 16 of x is 00000..00 or 111...1111
* so after shift, if x remains the same, then it means that x can be represent as 16-bit
*/
return !(((x << 16) >> 16) ^ x);
}
左移一个负值或一个移位值超出int
范围的数字有未定义的行为,右移一个负值是实现定义的,所以上面的解决方案是不正确的(虽然它可能是预期的溶液)。
答案 4 :(得分:2)
Loooong之前,这就是你在1K ZX 80或ZX 81计算机等极其有限的设备上节省内存的方法。在BASIC中,你会
Let X = NOT PI
而不是
LET X = 0
由于数字存储为4字节浮点数,后者比第一个NOT PI替代方案多2个字节,其中NOT和PI每个占用一个字节。
答案 5 :(得分:0)
在所有计算机体系结构中有多种编码方式的方法。使用2的补码时,这将永远为真:~0 == -1
。另一方面,一些计算机使用1的补码来编码负数,上面的例子是不正确的,因为~0 == -0
。是的,1s补码有负零,这就是为什么它不是很直观。
那么你的问题
mask & sth == sth
我个人的想法 - 尽可能地使您的代码与平台无关。成本相对较小,代码成为失败证明