Right shift (Division) -> ROUND TOWARD ZERO

10,329

Solution 1

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.

Solution 2

Do something conditionally depending on whether your value is positive or negative.

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

Solution 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).

Solution 4

I do this:

(value + 4) >> 3

Solution 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;
Share:
10,329
RealHIFIDude
Author by

RealHIFIDude

Updated on June 04, 2022

Comments

  • RealHIFIDude
    RealHIFIDude almost 2 years

    I am doing this..

    value >> 3;
    

    It is always going toward negative side.How do I round toward zero with right shift division?