~ 和 - 之间的区别
Difference between ~ and -
所以我在胡思乱想霍夫曼编码,我注意到一些我觉得我应该已经知道的东西,但遗憾的是我不知道。
问题在标题中,与此方法有关:
void BinWriter::writeBit(bool b) {
A ^= (-b^A)&(1UL << n++); // A is of type char
if (n == 8) {
ofd.write((char*)&A, 1);
n = 0;
}
}
如果我写 ~b
而不是 -b
,结果就会大不相同。为什么是这样? ~
不应该是否定运算符吗?在这种情况下,它与 -
有何不同?
Also Visual Studio (2017) 也警告我这两个运算符都是 'unsafe' 布尔类型,这是为什么?
您违反了整数提升。不太科学的解释是,对于某些运算符,如果没有显式定义,C++ 会尝试将内置整数类型(包括 bool
)转换为 int
。然后,这会导致以下结果:
#include <iostream>
int main()
{
std::cout << std::boolalpha;
std::cout << "~: " << ~true << ", " << ~false << "\n";
std::cout << "-: " << -true << ", " << -false << "\n";
std::cout << "!: " << !true << ", " << !false << "\n";
}
将打印
~: -2, -1
-: -1, 0
!: false, true
请注意 !
是这些运算符中唯一实际为 bool
定义的运算符,而其他两个强制整数提升(false
变为 0 和 true
变成 1).
-b^A
表示 "keep all the bits the same way if b
is false
, and flip them all if b
is true
",而 ~b^A
表示 "Flip all the bits all the time, but the last one only if b
is false
" - 完全不同的语义!
所以我在胡思乱想霍夫曼编码,我注意到一些我觉得我应该已经知道的东西,但遗憾的是我不知道。
问题在标题中,与此方法有关:
void BinWriter::writeBit(bool b) {
A ^= (-b^A)&(1UL << n++); // A is of type char
if (n == 8) {
ofd.write((char*)&A, 1);
n = 0;
}
}
如果我写 ~b
而不是 -b
,结果就会大不相同。为什么是这样? ~
不应该是否定运算符吗?在这种情况下,它与 -
有何不同?
Also Visual Studio (2017) 也警告我这两个运算符都是 'unsafe' 布尔类型,这是为什么?
您违反了整数提升。不太科学的解释是,对于某些运算符,如果没有显式定义,C++ 会尝试将内置整数类型(包括 bool
)转换为 int
。然后,这会导致以下结果:
#include <iostream>
int main()
{
std::cout << std::boolalpha;
std::cout << "~: " << ~true << ", " << ~false << "\n";
std::cout << "-: " << -true << ", " << -false << "\n";
std::cout << "!: " << !true << ", " << !false << "\n";
}
将打印
~: -2, -1
-: -1, 0
!: false, true
请注意 !
是这些运算符中唯一实际为 bool
定义的运算符,而其他两个强制整数提升(false
变为 0 和 true
变成 1).
-b^A
表示 "keep all the bits the same way if b
is false
, and flip them all if b
is true
",而 ~b^A
表示 "Flip all the bits all the time, but the last one only if b
is false
" - 完全不同的语义!