我正在阅读 JS 手册,发现了一个不错的技巧,即~val === (val != -1)
. 我发现它很好,并想在我的 C 代码中使用它。
它是便携式的吗?我检查了我的 GNU/Linux 机器,它可以工作。
编辑:似乎我问得不太清楚。当然,我知道,===
C 中没有。问题是,都是条件句
int val;
if (~val) {...}
if (val != -1) {...}
平等的?
我正在阅读 JS 手册,发现了一个不错的技巧,即~val === (val != -1)
. 我发现它很好,并想在我的 C 代码中使用它。
它是便携式的吗?我检查了我的 GNU/Linux 机器,它可以工作。
编辑:似乎我问得不太清楚。当然,我知道,===
C 中没有。问题是,都是条件句
int val;
if (~val) {...}
if (val != -1) {...}
平等的?
不,这不对。
首先,运算符 "===" 在 C 中不存在。其次,比较 "val != -1" 在 C 中返回 true (1) 或 false (0)。
你想完成什么?
以下答案是针对最初措辞的问题编写的,这使我和其他人认为他在问是否~ans
和(ans ^ -1)
等价。
这个技巧不像~val
它假设那样可移植-1 == 0b111111111...
,这仅在二进制补码机器上是正确的(当然,今天几乎适用于任何机器)。它利用了 xor 操作作为“受控反相器”的事实,翻转其左操作数中对应的右操作数位为 1 的每一位。
但是,替换可能~0
会-1
起作用。
在 , 的上下文中,if (exprA) vs if (exprB)
它们
是相等的。
exprA := ~val
exprB := val!=-1
在 (exprA) 和 (exprB) 评估为相同值的情况下,答案是否定的。
exprA := ~val
在这种情况下,等效表达式是
exprB := val ^ -1
,或者
exprB := val!=-1
, 在这种情况下,等价的表达式可以是
exprA := !!(~val)
修改后的问题有所不同,因为 (val!=-1) 在数值上计算为 0 或 1,但 if 语句可以使用任何非零值来表示条件为真。
所以答案取决于上下文。
val != -1 将是 1 或 0。
If val = 0, ~0 = 0xFFFFFFFF on a 32 bit machine with 32 bit integer.
If val = 1, ~1 = 0xFFFFFFFE on a 32 bit machine with 32 bit integer.
等等。
这在世界上如何等于 1 或 0?除了'val'的两个特定值之外还有什么?
根据 Aki 的说法:您的意思可能是 ~val = val ^= -1。
xor truth table:
--------------------
|A | B | A^B |
--------------------
|0 | 0 | 0 |
--------------------
|0 | 1 | 1 |
--------------------
|1 | 0 | 1 |
--------------------
|1 | 1 | 0 |
--------------------
example: val = 1:
1(val) is represented as : 0000 0000 0000 0000 0000 0000 0000 0001
-1 is represented as: 1111 1111 1111 1111 1111 1111 1111 1111
-------------------------------------------------------------------
(XOR VAL AND -1): 1111 1111 1111 1111 1111 1111 1111 1110
--------------------------------------------------------------------
[negate:0to1 1to0] ~val : 1111 1111 1111 1111 1111 1111 1111 1110
-------------------------------------------------------------------
由于这两者在逻辑上是相等的 - 并且所有机器都遵循逻辑,因此这必须在每台以 2 的补码方法存储负数的机器上工作。
顺便说一句:2 的补码是负数 + 1 的补码:
因此存储-1:
-1 = negative : 0000 0000 0000 0000 0000 0000 0000 0001
1' = 1s compliment: 1111 1111 1111 1111 1111 1111 1111 1110
2' = 2s compliemnt: 1111 1111 1111 1111 1111 1111 1111 1111
---------------------------------------------------------------