[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Bug in % (Float)?

Alex Gutteridge

8/30/2007 1:31:00 AM

On 30 Aug 2007, at 09:02, Charlie Lehardy wrote:

> So, can anybody tell me what's going on here? Are things really
> broken, or am I just
> expecting the wrong results?
>
> Thanks,
> Charlie

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/n...

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

Alex Gutteridge

Bioinformatics Center
Kyoto University



1 Answer

Charlie Lehardy

8/30/2007 7:00:00 PM

0

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/n...
>
> 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