# Rounding errors?

**URL:** <https://www.ruby-forum.com/t/rounding-errors/169644>\
**Category:** Ruby\
**Created:** [June 6, 2009, 4:07am UTC](https://www.ruby-forum.com/t/rounding-errors/169644 "2009-06-06T04:07:13Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![moredip](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/bbce88/32.png) [@moredip](https://www.ruby-forum.com/u/moredip)\
**Post date:** [June 6, 2009, 4:07am UTC](https://www.ruby-forum.com/t/rounding-errors/169644/1 "2009-06-06T04:07:13Z")

</div>

:~$ 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.

:~$ ruby -v  
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]

Cheers,  
Pete

---

<div class="post-metadata">

**Author:** ![moredip](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/bbce88/32.png) [@moredip](https://www.ruby-forum.com/u/moredip)\
**Post date:** [June 6, 2009, 4:15am UTC](https://www.ruby-forum.com/t/rounding-errors/169644/2 "2009-06-06T04:15:57Z")

</div>

Pete H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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

---

<div class="post-metadata">

**Author:** ![moredip](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/bbce88/32.png) [@moredip](https://www.ruby-forum.com/u/moredip)\
**Post date:** [June 6, 2009, 4:21am UTC](https://www.ruby-forum.com/t/rounding-errors/169644/3 "2009-06-06T04:21:12Z")

</div>

On Jun 5, 2009, at 10:07 PM, Pete H. wrote:

> :~$ 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.

> > sprintf “%0.30f”, 0.29  
> > =\> “0.289999999999999980015985556747”  
> > sprintf “%0.30f”, 0.29_100  
> > =\> “28.999999999999996447286321199499”  
> > sprintf “%0.30f”, (0.29_100).to\_i  
> > =\> “28.000000000000000000000000000000”

If you want to really understand what is going on:  
[http://docs.sun.com/source/806-3568/ncg\_goldberg.html](http://docs.sun.com/source/806-3568/ncg_goldberg.html)

Gary W.

---

<div class="post-metadata">

**Author:** ![moredip](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/bbce88/32.png) [@moredip](https://www.ruby-forum.com/u/moredip)\
**Post date:** [June 6, 2009, 5:09am UTC](https://www.ruby-forum.com/t/rounding-errors/169644/4 "2009-06-06T05:09:42Z")

</div>

Pascal J. Bourguignon wrote:

> $ clisp -q -norc -x ‘(values (truncate (\* 0.29 100)))’  
> 29

There’s nothing strange here, just IEEE floats, which don’t represent  
every decimal float:

irb(main):001:0\> (0.29)\*100  
=\> 29.0  
irb(main):002:0\> ((0.29)\*100).to\_i  
=\> 28  
irb(main):003:0\> ((0.29)\*100).round  
=\> 29  
irb(main):004:0\> ((0.29)\*100).floor  
=\> 28  
irb(main):006:0\> “%20.18f” % ((0.29)\*100)  
=\> “28.999999999999996447”  
irb(main):007:0\> “%20.18f” % 0.29  
=\> “0.289999999999999980”

---

<div class="post-metadata">

**Author:** ![moredip](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/bbce88/32.png) [@moredip](https://www.ruby-forum.com/u/moredip)\
**Post date:** [June 6, 2009, 5:47am UTC](https://www.ruby-forum.com/t/rounding-errors/169644/5 "2009-06-06T05:47:07Z")

</div>

On Jun 5, 2009, at 7:15 PM, Pascal J. Bourguignon wrote:

> $ clisp -q -norc -x ‘(values (truncate (\* 0.29 100)))’  
> 29
> 
> –  
> **Pascal B.**

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)

---

<div class="post-metadata">

**Author:** ![moredip](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/bbce88/32.png) [@moredip](https://www.ruby-forum.com/u/moredip)\
**Post date:** [June 6, 2009, 1:25pm UTC](https://www.ruby-forum.com/t/rounding-errors/169644/6 "2009-06-06T13:25:43Z")

</div>

On 06.06.2009 05:46, s.ross wrote:

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

Agreed. And, btw, with BigDecimal even Ruby comes up with more  
“natural” results:

require ‘bigdecimal’  
x = BigDecimal.new “0.29”  
x \*= 100  
puts x  
printf “%f %10.8f\n”, x, x

→

0.29E2  
29.000000 29.00000000

> However, the correct answer is: The  
> result of evaluating this expression is implementation-specific.

Actually, this is only half true: if the implementation is IEEE-754  
standards conform then it must yield certain results - regardless of  
implementation. I believe nowadays most if not all math libraries  
conform to the standard so you should expect to see the same results  
from all implementations. I would assume that differences are mostly  
due to numeric data type (see your C example) and conversion for  
printing (e.g. how many places are output by default).

> **[IEEE 754](https://en.wikipedia.org/wiki/IEEE_754)**
>
> The IEEE Standard for Floating-Point Arithmetic (IEEE 754) is a technical standard for floating-point arithmetic established in 1985 by the Institute of Electrical and Electronics Engineers (IEEE). The standard addressed many problems found in the diverse floating-point implementations that made them difficult to use reliably and portably. Many hardware floating-point units use the IEEE 754 standard.
> The standard defines:
> IEEE 754-2008, published in August 2008, includes nearly all of the or...

[http://grouper.ieee.org/groups/754/](http://grouper.ieee.org/groups/754/)

> The moral of the story is not “use Lisp”. The moral is use floating  
> point numbers with great care.

Exactly.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![moredip](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/bbce88/32.png) [@moredip](https://www.ruby-forum.com/u/moredip)\
**Post date:** [June 6, 2009, 10:03am UTC](https://www.ruby-forum.com/t/rounding-errors/169644/7 "2009-06-06T10:03:09Z")

</div>

“s.ross” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

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

My point being that there are some implementations that are more  
useful and helpful than others.
