Ran into an odd bug while trying to play around with some perlin noise functions. All of the sudden I got a off value in the middle of all of my calls. Traced it down to an inconsistent return value in fmod().
i=512;
cout << i << "," << fmod(i/102.4,1.f) << "," << fmod(i/102.4,1.f) << endl;
I would expect to get the following output.
512,0,0
But I don’t. I get this.
512,0,1
What is even MORE strange is that if I call the cout line several times, the error goes away on the later runs.
512,0,1
512,0,0
512,0,0
Hard coding the value into the function (replace all the ‘y’ with ‘512’) results in the correct results (always returns 0).
Has anyone ever seen a result like this?
Final Edit: This is almost certainly a bug in either GCC or glibc. Simply declaring a function that calls fmod somewhere else in the code (even if that function doesn’t get called) makes the problem go away.
I suggest passing
-fno-builtinsto the compiler to work around this. Thas seems to fix it for me.I’m able to reproduce this in GCC 4.5.3 for cygwin.
This only happens if the
ivariable is non-const [Edit: Probably because it’s encouraging the compiler to use a temporary to store the result of the initial division). My even simpler C program to test:Which outputs:
I’ve tried looking through the asm output, but my x87-foo is weak. Can anyone else see what’s wrong? I’ll keep looking in the meantime:
[Edit: Note, it’s always the first call to fmod that is returning the strange result (never later one’s). The fmod calls are being evaluated right-to-left.
[Edit 2: Defining a function,
double my_fmod(double a, double b) { return fmod(a, b); }and passing the calls through that makes the problem go away. ]