0

I have a function that does rounding operation as shown below. It takes 64bit integer as input and gives 32bit integer as output. While converting, a factor of 0x40000000 is being added to the input. What is the reason behind it?

int rounder(long long int in)
{
  INT64 out;
  if ((in >> 32) == 0x7FFFFFFF)
    out = in;
  else
    out = (INT64)0x40000000 + in; 
  out = out >> 31; 
  return (INT32)out;
}
rkc
  • 111
  • 8

2 Answers2

2

Let's start with some smaller numbers, because they're easier!

Using conventional rounding, x.49999... or less should round down to x, x.50000... or more should round up to (x+1).

(There are lots of different rounding methods, but this is the one most learn at school.)

Whenever you do integer division (or conversion of a floating point value to an integer), you simply throw away the fractional part. Hence:

6/2 == 3.0  --> 3
5/2 == 2.5  --> 2

A neat 'trick' is to add half-the-divisor (1, in this case) before division. As if by magic, you get the right rounding! eg:

6/2  becomes  (6+1)/2  == 7/2 == 3.5  --> 3
5/2  becomes  (5+1)/2  == 6/2 == 3.0  --> 3

You can see why this works by looking at it this way:

 5/2  becomes  (5+1)/2  ==   5/2 + 1/2
13/6  becomes (13+3)/6  ==  13/6 + 3/6   == 13/6 + 1/2

You're adding half to the real answer. Anything less than x.5 will still be less than x+1 so will still round down, anything of x.5 or more will become x+1 or more so will round up.

Now to your actual question: This idea works with all divisors; you're shifting down by 31, which is the same as dividing by 2^31. So 'half-the-divisor' is 2^30, or 0x40000000.

Beware: as others have noted, this 'trick' only works for positive numbers (you need to subtract if it's negative, but it's a can of worms).

There is a lot to consider in this topic; it's not simple to get your head around. As ever, try some easy examples for yourself and see what happens.

Edd Inglis
  • 1,067
  • 10
  • 22
0

The input appears to be a 64-bit fixed point number with 31 fraction bits. The 0x40000000 value is added to round the number up if it has a fractional part >= 0.5. The if is used to avoid possible overflow when factoring in the rounding.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • Hi, your answer seems to be helpful to me. can you explain in detail? – rkc Feb 20 '20 at 05:04
  • Fixed point numbers are integers where you have an imaginary "decimal point" (actually a "binary point" ;-) between two defined bits. Bits left of it are the integer part, bits right of it are the fractional part. – the busybee Feb 20 '20 at 06:53