问题
I am doing this..
value >> 3;
It is always going toward negative side.How do I round toward zero with right shift division?
回答1:
Do something conditionally depending on whether your value is positive or negative.
if( value < 0 ) {
-((-value) >> 3);
}
else {
value >> 3;
}
回答2:
Gez, the answers were pretty bad ; you want to solve that without branching, but without breaking your positive numbers either.
Here it is :
(int)(value+(((unsigned)value)>>31)) >> 3
The cast to (unsigned) is required to perform a logical shift and obtain just the sign bit, then we need to cast back to (int) to perform an arithmetic right shift.
The code above made the assumption that your int data type is 32 bits, you should of course use data types such as int32_t in such cases.
回答3:
Try the following expression instead:
(value < 0) ? -((-value) >> 3) : value >> 3;
That will force a negative number to be positive first so that it round towards zero, then changes the result back to negative.
This may cause issues for the minimum integer under two's complement notation (not ones' complement or sign/magnitude) but you could put a separate check in to catch that first.
Or (and this is probably preferable) you could just stop trying to divide by eight with a right shift altogether, instead choosing:
value = value / 8;
Then let your compiler choose the best way of doing that. You should be coding to specify intent rather than trying to optimise (needlessly, unless you have a truly brain-dead compiler).
回答4:
I do this:
(value + 4) >> 3
回答5:
Add 7 to the number if it is negative in order to round to zero.
This is how you do that:
int mask = x >> 31;
x = (x + (7 & mask)) >> 3;
回答6:
You are encountering 'signed' shifting, when what you seem to want is unsigned shifting. Try casting it to unsigned first, like this
x = ((unsigned) x) >> 3;
.. or you could just use division.
来源:https://stackoverflow.com/questions/1463736/right-shift-division-round-toward-zero