Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to speed up floating-point to integer number conversion? [duplicate]

Tags:

We're doing a great deal of floating-point to integer number conversions in our project. Basically, something like this

for(int i = 0; i < HUGE_NUMBER; i++)
     int_array[i] = float_array[i];

The default C function which performs the conversion turns out to be quite time consuming.

Is there any work around (maybe a hand tuned function) which can speed up the process a little bit? We don't care much about a precision.

like image 461
Serge Avatar asked Jan 09 '09 20:01

Serge


People also ask

How would you convert float into integers?

A float value can be converted to an int value no larger than the input by using the math. floor() function, whereas it can also be converted to an int value which is the smallest integer greater than the input using math. ceil() function.

What happens when you convert a float to an int?

Convert a float to an int always results in a data loss. The trunc() function returns the integer part of a number. The floor() function returns the largest integer less than or equal to a number. The ceil() function returns the smallest integer greater than or equal to a number.

Why is float faster than double?

Floats are faster than doubles when you don't need double's precision and you are memory-bandwidth bound and your hardware doesn't carry a penalty on floats. They conserve memory-bandwidth because they occupy half the space per number. There are also platforms that can process more floats than doubles in parallel.

Which method is used to convert integer data type to float?

A floating-point can be converted to an integer using the int() function. To do this pass a floating-point inside the int() method. Similarly an integer can be converted to float using the float() method. To do this pass an integer inside the float() method.


2 Answers

Most of the other answers here just try to eliminate loop overhead.

Only deft_code's answer gets to the heart of what is likely the real problem -- that converting floating point to integers is shockingly expensive on an x86 processor. deft_code's solution is correct, though he gives no citation or explanation.

Here is the source of the trick, with some explanation and also versions specific to whether you want to round up, down, or toward zero: Know your FPU

Sorry to provide a link, but really anything written here, short of reproducing that excellent article, is not going to make things clear.

like image 164
Larry Gritz Avatar answered Oct 18 '22 14:10

Larry Gritz


inline int float2int( double d )
{
   union Cast
   {
      double d;
      long l;
    };
   volatile Cast c;
   c.d = d + 6755399441055744.0;
   return c.l;
}

// this is the same thing but it's
// not always optimizer safe
inline int float2int( double d )
{
   d += 6755399441055744.0;
   return reinterpret_cast<int&>(d);
}

for(int i = 0; i < HUGE_NUMBER; i++)
     int_array[i] = float2int(float_array[i]);

The double parameter is not a mistake! There is way to do this trick with floats directly but it gets ugly trying to cover all the corner cases. In its current form this function will round the float the nearest whole number if you want truncation instead use 6755399441055743.5 (0.5 less).

like image 43
deft_code Avatar answered Oct 18 '22 14:10

deft_code