【发布时间】:2011-10-28 05:44:52
【问题描述】:
所有这些功能在我的机器上都给出了预期的结果。他们都在其他平台上工作吗?
更具体地说,如果 x 在 1 的补码机器上具有位表示 0xffffffff 或在有符号幅度机器上具有 0x80000000,那么标准对 (unsigned)x 的表示有何规定?
另外,我认为 v2、v2a、v3、v4 中的(无符号)强制转换是多余的。这是正确的吗?
假设 sizeof(int) = 4 和 CHAR_BIT = 8
int logicalrightshift_v1 (int x, int n) {
return (unsigned)x >> n;
}
int logicalrightshift_v2 (int x, int n) {
int msb = 0x4000000 << 1;
return ((x & 0x7fffffff) >> n) | (x & msb ? (unsigned)0x80000000 >> n : 0);
}
int logicalrightshift_v2a (int x, int n) {
return ((x & 0x7fffffff) >> n) | (x & (unsigned)0x80000000 ? (unsigned)0x80000000 >> n : 0);
}
int logicalrightshift_v3 (int x, int n) {
return ((x & 0x7fffffff) >> n) | (x < 0 ? (unsigned)0x80000000 >> n : 0);
}
int logicalrightshift_v4 (int x, int n) {
return ((x & 0x7fffffff) >> n) | (((unsigned)x & 0x80000000) >> n);
}
int logicalrightshift_v5 (int x, int n) {
unsigned y;
*(int *)&y = x;
y >>= n;
*(unsigned *)&x = y;
return x;
}
int logicalrightshift_v6 (int x, int n) {
unsigned y;
memcpy (&y, &x, sizeof (x));
y >>= n;
memcpy (&x, &y, sizeof (x));
return x;
}
【问题讨论】:
-
为什么不直接除以 (2^n) 让编译器进行优化?
-
假设 2 的补码:logicalrightshift (-1,1) 应该是 0x7fffffff,但 -1 / 2 = 0
-
@user1016492:如果您的机器上的
UINT_MAX等于0xffffffff,那么(unsigned)-1 >> 1保证为0x7fffffff,不管有符号数字使用什么表示。 -
@Mat:
2^n是 C 中的异或运算... -
@Deitrich:也许这就是他不使用代码标记的原因。当印刷限制阻止上标时,使用 ^ 进行求幂是常见用法。在这种情况下,读者必须应用上下文来消除歧义。我认为 Mat 的评论在上下文中已经足够清楚了。
标签: c standards bit-shift zero negative-number