Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby - Multiplication issue

My output is like this -

ruby-1.9.2-p290 :011 > 2.32 * 3
=> 6.959999999999999

And I remember sometime back on another machine I had got it like.. 2.32 * 3 = 6

What is my mistake? Thanks a ton for reading this. :)

like image 301
Anuprit Avatar asked Dec 07 '22 18:12

Anuprit


2 Answers

If you really want to round down to an integer then just

(3 * 2.32).to_i

but I think that's unlikely. Usually you just want to format the slightly imprecise floating point number to something like this

"%0.2f" % (3 * 2.32) 
=> "6.96"

If you really want to work with the exact representation then you can use BigDecimal.

require 'BigDecimal'
(3 * BigDecimal.new("2.32")).to_s("F")
=> "6.96"

PS. Recommended read http://floating-point-gui.de/ DS.

like image 80
Jonas Elfström Avatar answered Dec 22 '22 23:12

Jonas Elfström


I cannot tell you about Ruby, so please forgive me. But frankly the principles stay the same, so I hope that'll help:

Python 2.7.1 (r271:86832, Jun 16 2011, 16:59:05) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 2.32 * 3
6.959999999999999

As you can see, Python does the same.

System.out.println(2.32 * 3);
6.959999999999999

Java does the same! So what's wrong with it?

Let's try to move to BigDecimals:

System.out.println(new BigDecimal(2.32));
2.319999999999999840127884453977458178997039794921875

What you see here is what actually is meant by 2.32. It's just that in most cases print, or toString(), or whatever your language uses for converting floats to strings, rounds the numbers a bit.

The inexact value, due to the fact that floats are in fact binary-represented reals, not decimal ones—which, in turn, makes those binaries repeating, or recurring. And as you can guess, repeating real in a limited space won't ever be exact.

Actually, I was lying when I said the scary decimal above is what is meant by 2.32— the proper wording would be, "it's the closest decimal Java could get to approximate the actual value of 2.32".

Read more here: http://floating-point-gui.de/

like image 30
alf Avatar answered Dec 22 '22 23:12

alf