# Thread: fmod vs. modf vs. floor

1. ## fmod vs. modf vs. floor

Probably a trivial question, but what would be the best/fastest way to get the fractional part of a float?

can do...
double tmp = a * b;
tmp -= floor(tmp);

or

fmod(a * b, 1.0);

or

modf(a * b, void);

2. I dunno, but you could write a simple program to test it.

I think your first version would have problems with negative numbers though. AFAIK floor would set -4.5 to -5. If thats the case you should cast to int instead like: tmp -= (int)tmp;

3. I should've mentioned, I was only concerned with positive values.

4. Well I think that flooring and subtracting would be faster than fmod, and casting to int would be faster than calling floor. But thats just what I would expect.

5. Hmmm...yes, but you'd have to cast back to double to subtract.

Btw, love the title of your new website..."Code & S__t"

6. I would expect modf to be fastest, because it is designed to do specifically what you ask. Judging by the glibc implementation of modf, I'd say this is the case. It does some simple bit manipulations that essentially copies out the fractional part.

7. Originally Posted by DoctorBinary
I would expect modf to be fastest, because it is designed to do specifically what you ask. Judging by the glibc implementation of modf, I'd say this is the case. It does some simple bit manipulations that essentially copies out the fractional part.
I'll have to look at that one day. Piqued my curiosity in a perverse manner.

Presumably that working is based on the floating value being in some specified range (magnitude less than some threshold). Not all floating point values (eg with a large exponent) will even have a fractional part.

8. Originally Posted by grumpy
I'll have to look at that one day. Piqued my curiosity in a perverse manner.

Presumably that working is based on the floating value being in some specified range (magnitude less than some threshold). Not all floating point values (eg with a large exponent) will even have a fractional part.
Those are the easy ones: return 0.

9. Originally Posted by DoctorBinary
I would expect modf to be fastest, because it is designed to do specifically what you ask. Judging by the glibc implementation of modf, I'd say this is the case. It does some simple bit manipulations that essentially copies out the fractional part.
Do you absolutely have to assign the integral part to another value though? Can I just stick void in there or something? I'm only interested in the fractional part.

10. Originally Posted by Epy
Do you absolutely have to assign the integral part to another value though? Can I just stick void in there or something? I'm only interested in the fractional part.
You have to pass a valid pointer in there, but you are not required to care about it.

11. I did a quick performance test on Windows (Visual C++) and, of the three methods -- modf, fmod, and floor -- floor ran faster than modf, and both ran much faster than fmod.

Of course I don't have the source code for Windows, but looking at the glibc source for floor, it does "bit twiddling" just like modf. Maybe it's faster because it doesn't pass the extra parameter? I don't know.

One thing that may be an issue with the floor method is floating point round off error. You have to subtract out the floor to get the fractional part. modf just extracts it directly. I'll have to think about this some more...

12. Excellent, thanks Doc. Floor(x) it is.

13. I still think casting would be quicker as you have to deal with function overhead.

Heres the prog I used:
Code:
```#include <stdio.h>
#include <math.h>

int main(){
float num = 12.5678, ans;
int i;
for(i=0; i<10000000; i++){
//ans = num-((int)num);  //use cast
ans = num-floor(num);   //use floor
}
printf("%f\n", ans);
return 0;
}```
Its very crude. These were my typical timed results:

using floor:
real 0m0.468s
user 0m0.468s
sys 0m0.000s
using cast:
real 0m0.163s
user 0m0.140s
sys 0m0.008s
When I compiled with 02 optimisations the prog ran in 0.004s, but I'm guessing the optimiser removed the redundant operations.

14. I added a "cast" testcase and indeed it ran faster than floor (though not a big difference like you saw mike_g). I was using doubles though (with a cast to "long long" to match).