On 8/29/07, Alex Gutteridge <alexg / kuicr.kyoto-u.ac.jp> wrote: > As Florian says, the problem is inherent with floating point values. > The Python docs have a good section which explains how 0.1 cannot be > represented as a binary fraction: > > http://docs.python.org/tut/node16.html > > Ruby just uses your systems C functions (fmod in this case) to do > these calculations and they show the same behavior: > > [alexg / powerbook]/Users/alexg/Desktop(209): cat test.c > #include <math.h> > #include <stdio.h> > > int main(){ > printf("fmod of 1 / 0.1 is %lf\n",fmod(1,0.1)); > return 0; > } > [alexg / powerbook]/Users/alexg/Desktop(210): gcc -lm test.c -o modtest > [alexg / powerbook]/Users/alexg/Desktop(211): ./modtest > fmod of 1 / 0.1 is 0.100000 Yes, but if you use modf, you DO get the correct result. And ruby only uses fmod if it's available and uses modf instead. However, considering that modf is returning the incorrect results (and fmod returns the correct ones), maybe it shouldn't be used? For example, to build upon your C code: scott9:mms$ cat test.c #include <math.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char * argv[]) { double div, mod, x, y, z; x = 1.0; y = 0.1; if (argc > 1) x = atof(argv[1]); if (argc > 2) y = atof(argv[2]); modf(x/y, &z); mod = x - z * y; printf("fmod of %lf / %lf is %lf\n", x, y, fmod(x, y)); printf("modf of %lf / %lf is %lf\n", x, y, mod); return 0; } scott9:mms$ gcc -lm test.c -o modtest scott9:mms$ ./modtest fmod of 1.000000 / 0.100000 is 0.100000 modf of 1.000000 / 0.100000 is -0.000000 scott9:mms$ ./modtest 5 0.5 fmod of 5.000000 / 0.500000 is 0.000000 modf of 5.000000 / 0.500000 is 0.000000 scott9:mms$ ./modtest 1 0.5 fmod of 1.000000 / 0.500000 is 0.000000 modf of 1.000000 / 0.500000 is 0.000000 I also thought I'd throw in that example of 0.5 as the divisor too (it works properly in Ruby too). Anyway, what's the reasoning for preferring to use fmod over modf? If it's simply a performance reason, isn't giving correct results preferable to having a bit of speed increase? Lastly, if floats are so problematic, why even use them in these sorts of operations? Why not have flo_mod convert to a decimal first (multiply by some factor of 10) and then divide the by that factor again? Or again, maybe flodivmod should just use modf since it appears to work properly? Thanks Again, Charlie