fastest way to do (int) floor(double) nowadays ?

Started by
9 comments, last by japro 12 years, 1 month ago
Standard C++ functions to convert a float or double to int, or to take the integer floor of a float or double, have always been very slow.

I've seen various alternatives in the past, but I'm wondering: what is generally considered the best (as in fastest) solution these days?

This one (using standard functions) obviously sucks:
inline int MyFloor( double x )
{
return static_cast<int> (floor(x));
}


When limiting to x86, I guess some inline asm FISTP approach might be faster, although I guess that depends on the current rounding mode (and changing + restoring that kinda defeats the purpose).

I've also seen several methods using 'magic numbers': interpreting the binary float representation as integer (i.e. no conversion takes place), adding some magic value, and you have a valid integer. Probably limited precision, but it seemed to do the job.

What should I use? (besides optimizing my entire algorithm in the first place, and only consider this kind of optimizations at the end - I know)
Advertisement
there is a fast cast with SIMD (float to int) with 2 instructions, there should be also a double floor to int.
It is already optimized.

If you have a glance at the MSDN documentation you'll see it among the intrinsicly-implemented functions.
Unless I was doing lots of these inside a really tight deeply nested loop (in which case I'd be asking serious questions about my design), and unless I knew it was a measurable bottleneck, I'd generally just trust the compiler to do the right thing here.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

Just assign the double to an int? The floating point value is instantly truncated without casts or (formal) conversions.


inline int MyFloor(double d) {
int f = d;
return f;
}

Just assign the double to an int? The floating point value is instantly truncated without casts or conversions.


inline int MyFloor(double d) {
int f = d;
return f;
}


If your compiler isn't giving you a warning about that, then you're using your compiler wrong. Casting definitely should be used.

Although I will ask (in partial agreement with forb's comment about truncation, though there should be a cast), is there a reason for flooring before casting?
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Casting a floating point value to an integer rounds towards zero, but the floor-function rounds towards negative infinity. Thus, simply casting the value to an integer does not round the value in the same way as the OP requested.

Casting a floating point value to an integer rounds towards zero, but the floor-function rounds towards negative infinity. Thus, simply casting the value to an integer does not round the value in the same way as the OP requested.

Ah, I see. Subtle difference. Thanks.
[size=2][ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]
Smart arse answer here tongue.png -- but the fastest way is probably to keep the result in floating-point and avoid mixing integer and float math together, especially on PPC CPUs wink.png
I agree with Hodgman. The biggest problem here is the LHS caused by moving the value from the FPU to integer registers. For the biggest bang for your buck, leave the value in floating-point or move the math to use SIMD or some other registers that can store both floats and ints (if your hardware supports it).
-- gekko

This topic is closed to new replies.

Advertisement