我对第三个参数感到好奇,即来自 LLVM llvm/ADT/APInt.h
header 的 APInt(unsigned numBits, uint64_t val, bool isSigned = false)
中的 bool 值 isSigned
。
无论我将其设置为什么,getActiveBits()
或 getMinSignedBits()
等函数的结果根本不会改变。
此外,如果我想获取有符号/无符号值,我可以使用 getSExtValue()
或 getZExtValue()
。
isSigned
的值对他们来说也不重要。
那么什么时候 isSigned
才重要呢?
最佳答案
TL;DR: isSigned
仅对 numBits > 64
重要。
sizeof(val)
只有 64 位。想象一下,您想要将有符号值存储在大小 > 64 位
的整数中。
如果值为负,则所有高位必须设置为
1
,因为负值通常存储为 two's complement .如果值为正,则所有高位必须设置为
0
示例
假设您想要以 128 位存储 -1。
持有-1的uint64_t val
的二进制表示是
1111111111111111111111111111111111111111111111111111111111111111
这只有 64 位,所以还剩下 64 位需要填充。如果没有 isSigned
值,就不可能知道这些位是否应该为1,从而导致-1 或零 strong>,结果为 18446744073709551615。
长解释
看看source code揭示了 isSigned
仅在某些情况下使用:
APInt(unsigned numBits, uint64_t val, bool isSigned = false)
: BitWidth(numBits) {
assert(BitWidth && "bitwidth too small");
if (isSingleWord()) {
U.VAL = val;
clearUnusedBits();
} else {
initSlowCase(val, isSigned);
}
}
根据its function header , isSingleWord
returns true if the number of bits <= 64, false otherwise.
因此该行
if (isSingleWord()) {
检查值的存储是否占用比 val
本身更多的内存。
如果numBits
大于64,APInt::initSlowCase
被调用:
void APInt::initSlowCase(uint64_t val, bool isSigned) {
U.pVal = getClearedMemory(getNumWords());
U.pVal[0] = val;
if (isSigned && int64_t(val) < 0)
for (unsigned i = 1; i < getNumWords(); ++i)
U.pVal[i] = WORDTYPE_MAX;
clearUnusedBits();
}
此函数复制 val
变量中的值并将位填充到 numBits
。
这是必要的,因为负值存储为二进制补码。如果设置了 isSigned
并且 val
为负值,则高字的所有位都设置为 1。
关于c++ - APInt(unsigned numBits, uint64_t val, bool isSigned = false) 中的参数 bool 有何用途?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57409882/