我今天看到一个代码示例,它使用以下形式检查-1是否为无符号的64位整数:
if (a == (uint64_t)~0)
是否有任何用例需要与~0
进行比较而不是std::numeric_limits<uint64_t>::max()
或直接-1
?原来的意图对我来说并不清楚,因为我之前没有看到这样的比较。
为了澄清,比较是检查错误条件,其中无符号整数类型的所有位都设置为1
。
更新
根据https://stackoverflow.com/a/809341/1762276,-1
并不总是代表翻转到1
但~0
的所有位。这是对的吗?
我建议你完全按照你所展示的那样去做,因为它是 最直接的一个。初始化为-1,它将始终有效, 独立于实际的符号表示,有时〜 有令人惊讶的行为,因为你必须有权利 操作数类型。只有这样你才能获得最高的价值 无符号类型。
我相信只要~0
始终为正确的类型(如图所示),就会处理此错误情况。所以这表明(uint64_t)~0
确实是一个更准确的无符号类型的门户表示,所有位都被翻转了?
以下所有情况似乎都是正确的(GCC x86_x64):
#include <iostream>
#include <limits>
using namespace std;
int main() {
uint64_t a = 0xFFFFFFFFFFFFFFFF;
cout << (int)(a == -1) << endl;
cout << (int)(a == ~0) << endl;
cout << (int)(a == (uint64_t)-1) << endl;
cout << (int)(a == (uint64_t)~0) << endl;
cout << (int)(a == static_cast<uint64_t>(-1)) << endl;
cout << (int)(a == static_cast<uint64_t>(~0)) << endl;
cout << (int)(a == std::numeric_limits<uint64_t>::max()) << endl;
return 0;
}
结果:
1
1
1
1
1
1
1
答案 0 :(得分:4)
通常,您应该在应用运算符之前进行转换,因为根据源类型是否已签名,转换为更宽的无符号类型可能会也可能不会导致符号扩展。
如果您希望设置所有位的基本类型T
的值,则最便携的方法是~T(0)
。它也适用于任何类似数字的类。
正如彬格莱先生所说,来自stdint.h
的类型保证是两个补码,因此-T(1)
也会给出一个设置了所有位的值。
您引用的来源有正确的想法,但错过了一些细节,例如(T)~0u
和(T)-1u
都不会与~T(0u)
和-T(1u)
相同。 (公平地说,litb并没有谈论你所链接的答案中的扩大)
请注意,如果没有变量,只有一个未填充的文字0
或-1
,则保证源类型已签名,并且上述问题均不适用。但是,为什么在处理文字时编写不同的代码,当普遍正确的代码不再复杂时?
答案 1 :(得分:1)
std::numeric_limits<uint64_t>::max()
与(uint64_t)~0
相同,与(uint64_t)-1
查看此代码示例:
#include <iostream>
#include <stdint.h>
using namespace std;
int main()
{
bool x = false;
cout << x << endl;
x = std::numeric_limits<uint64_t>::max() == (uint64_t)~0;
cout << x << endl;
x = false;
cout << x << endl;
x = std::numeric_limits<uint64_t>::max() == (uint64_t)-1;
cout << x;
}
<强>结果:强>
0
1
0
1
所以在代码中编写
(uint64_t)~0
或(uint64_t)-1
比std::numeric_limits<uint64_t>::max()
更简单。
答案 2 :(得分:1)
像uint64_t
这样的固定宽度整数类型是guaranteed,以二进制补码表示,因此对于那些-1
和~0
是等价的。对于普通的整数类型(如int
或long
),情况不一定如此,因为C ++标准没有指定它们的位表示。