会丢失符号:将低位清零
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。
在十六进制中DIM
是00001000
,DIM-1
是00000FFF
,~(DIM-1)
是FFFFF000
。然后 &
操作保留在 ~(DIM-1)
中设置的所有位并将在 ~(DIM-1)
中清除的所有位清零。所以低 12 位被置零,高 20 位被保留。由于符号位是最高位,因此它被保留。
然而,从技术上讲,当用于负数时这是未定义的行为。在那种情况下,origin[0] & ~(DIM - 1)
的结果是一个很大的无符号数,当分配给 mVec[0]
(有符号数)时会溢出。不过在现实世界中并不是真正的问题。
我有一个 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。
在十六进制中DIM
是00001000
,DIM-1
是00000FFF
,~(DIM-1)
是FFFFF000
。然后 &
操作保留在 ~(DIM-1)
中设置的所有位并将在 ~(DIM-1)
中清除的所有位清零。所以低 12 位被置零,高 20 位被保留。由于符号位是最高位,因此它被保留。
然而,从技术上讲,当用于负数时这是未定义的行为。在那种情况下,origin[0] & ~(DIM - 1)
的结果是一个很大的无符号数,当分配给 mVec[0]
(有符号数)时会溢出。不过在现实世界中并不是真正的问题。