会丢失符号:将低位清零

Would sign be lost: zeroing out the low-order bits

我有一个 Coord class 这样的:

class Coord
{
public:
    Coord(int32_t x, int32_t y, int32_t z): mVec{{x, y, z}} {}
    
    int32_t operator[](size_t i) const { assert(i < 3); return mVec[i]; }

private:
    std::array<int32_t, 3> mVec
}

现在我用我的 class:

Coord origin(-1, 2, -4);

uint32_t DIM = 1 << 12; // 2 ^ 12

// zero out the low-order bits
Coord originAfter = Coord(origin[0] & ~(DIM - 1),
                          origin[1] & ~(DIM - 1),
                          origin[2] & ~(DIM - 1));

originAfter是否失去了origin的符号?

更新

代码可用 here

在十六进制中DIM00001000DIM-100000FFF~(DIM-1)FFFFF000。然后 & 操作保留在 ~(DIM-1) 中设置的所有位并将在 ~(DIM-1) 中清除的所有位清零。所以低 12 位被置零,高 20 位被保留。由于符号位是最高位,因此它被保留。

然而,从技术上讲,当用于负数时这是未定义的行为。在那种情况下,origin[0] & ~(DIM - 1) 的结果是一个很大的无符号数,当分配给 mVec[0](有符号数)时会溢出。不过在现实世界中并不是真正的问题。