我有一个关于
bitwise not
和 logical not
的问题,希望有人能为我解答。
所以我知道以下作品:
!true == false
!false == true
我以为
bitwise not
可以做同样的事情,但它显然不能。
假设我有一个布尔值:
bool test = true;
然后当我打印出
~test
时,输出是true
。
如果布尔值是
bool test = false;
然后当我打印出
~test
时,输出是true
,这是预期的。然而,当我再次执行~test
时,它不会回到false
。
由于某种原因,
bitwise not
无法将布尔值从true
翻转为false
。
有人有答案吗?
根据 C++ 标准 ([expr.unary.op]) 的 §5.3.1.10,
~
运算符采用整型(或无作用域枚举类型)操作数并执行整型提升,其中~
操作是其提升的操作数的类型。这意味着布尔值首先转换为积分(0
表示 false
,1
表示 true
)。根据您的上下文,~
运算的结果将转换回布尔值:false
表示 0
,true
表示所有非零值。
如果您有布尔值
x
,则可以将 ~x
视为 ~static_cast<int>(x)
,将 x = ~x
视为 x = ((~static_cast<int>(x)) != 0)
。
因此:
bool a = false;
bool b = ~a; // b = (~static_cast<int>(a) != 0)
// b = (~static_cast<int>(false) != 0)
// b = (~0 != 0)
// b = (0xffffffff != 0)
// b = true
bool c = ~b; // c = (~static_cast<int>(b) != 0)
// c = (~static_cast<int>(true) != 0)
// c = (~1 != 0)
// c = (0xfffffffe != 0)
// c = true
理解正在发生的事情的关键是意识到正在发生隐式转换。 ~
运算符应用于整数并返回整数,因此操作数必须先转换为整数,然后在赋值之前将结果转换为布尔值。
false
转换为 0,
true
转换为 1。在另一个方向,0 转换为
false
,任何非零值 转换为
true
。
~1
非零,因此转换为
true
。
true
转换为
0x00000001
。
~
进行按位求反,翻转其所应用的值中的每一位:
~0x00000001 == 0xfffffffe
,非 0,因此计算结果为 true。
false
会变为
0x00000000
,而
~0x00000000 == 0xffffffff
,转换为
bool
后会变为
true
。
true
时,
~
值将转换回
0x00000001
,不是
0xffffffff
,你又回到了起点。
bool
转换为
int
:
true ==> 1
false ==> 0
将
int
转换为
bool
:
zero value ==> false
non-zero value ==> true
从这里开始,你的问题的答案很简单:
~true == ~1
~1 != 0
~1 == true
当且仅当
~true == false
转换为
true
时,您对
~0
的期望才有效:
~true == ~~0
~~0 == 0
0 == false
~
上应用运算符
bool
之前,会发生到
int
的转换。因此,
~true
是
~int(true)
,它不为零。