右移(分部) - > RENT TOWARD ZERO

时间:2009-09-23 02:57:20

标签: c bit-manipulation

我这样做..

value >> 3;

它总是走向负面。如何通过右移除法向零舍入?

6 个答案:

答案 0 :(得分:3)

根据您的价值是正面还是负面,有条件地做一些事情。

if( value < 0 ) {
    -((-value) >> 3);
}
else {
    value >> 3;
}

答案 1 :(得分:3)

请尝试使用以下表达式:

(value < 0) ? -((-value) >> 3) : value >> 3;

这将迫使负数首先为正数,使其向零舍入,然后将结果更改为负数。

这可能导致二进制补码表示法下的最小整数问题(不是补码或符号/幅度),但您可以先单独检查以捕获它。

或者(这可能更可取)你可以停止试图除以8并完全右移,而是选择:

value = value / 8;

然后让您的编译器选择最佳方式。你应该编码来指定 intent ,而不是试图优化(不必要,除非你有一个真正的脑死亡编译器)。

答案 2 :(得分:3)

Gez,答案非常糟糕;你想在没有分支的情况下解决这个问题,但也不要打破正数。

这是:

(int)(value+(((unsigned)value)>>31)) >> 3

转换为(无符号)需要执行逻辑移位并仅获取符号位,然后我们需要强制转换为(int)以执行算术右移。

上面的代码假设您的int数据类型是32位,在这种情况下,您当然应该使用诸如int32_t之类的数据类型。

答案 3 :(得分:1)

我这样做:

(value + 4) >> 3

答案 4 :(得分:0)

当你看起来想要的是无符号换档时,你会遇到'签名'换档。首先尝试将其转换为无符号,如此

x = ((unsigned) x) >> 3;

..或者你可以使用师。

答案 5 :(得分:0)

如果数字为负数,则将数字加7,以便舍入为零。

这就是你这样做的方式:

int mask = x >> 31;
x = (x + (7 & mask)) >> 3;