Steve Ross
6/6/2009 3:46:00 AM
On Jun 5, 2009, at 7:15 PM, Pascal J. Bourguignon wrote:
> Pete Hodgson <ruby-forum@thepete.net> writes:
>
>> :~$ ruby -e "p ((0.29)*100).to_i"
>> 28
>>
>> Really?! I know that digital storage of floating point numbers can
>> lead
>> to things like this, but this one seems a little extreme to me.
>
> You may try a true Lisp instead of a Matzacred Lisp:
>
> $ clisp -q -norc -x '(values (truncate (* 0.29 100)))'
> 29
>
> --
> __Pascal Bourguignon__
The result of the calculation is undefined in pretty much any
language. The loose definition of the expression is "return a value
100 times a value approximating 29 and truncated to an integer using
the algorithm of your choice." So, you claim the *only* right answer
must be the one yielded by Lisp. However, the correct answer is: The
result of evaluating this expression is implementation-specific.
In C:
#include <stdio.h>
int main(void) {
double d = 0.29;
float f = 0.29;
printf("double truncated to integer is: %i\n", (int)(d * 100));
printf("float truncated to integer is: %i\n", (int)(f * 100));
return 0;
}
Would ANSI[1] C results be correct enough to be used as a gold
standard? Well, if so, the result of the program above is:
$ ./foo
double truncated to integer is: 28
float truncated to integer is: 29
The moral of the story is not "use Lisp". The moral is use floating
point numbers with great care. Oh, geez, I totally forgot, this is a
Ruby list, not a C list.
[1] gcc version 4.0.1 (Apple Inc. build 5488)