4

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

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
Anuprit
  • 95
  • 1
  • 4

4 Answers4

7

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.

Jonas Elfström
  • 30,834
  • 6
  • 70
  • 106
  • Thanks a lot! This will print the real thing. But my real problem is different though... I want to round a float to precision up to two digits and store it in database. But it round() is not working for 2.33333333. – Anuprit Oct 20 '11 at 21:33
  • In what way isn't it working? `2.333333333333.round(2)` `=> 2.33` – Jonas Elfström Oct 21 '11 at 06:31
  • I got it fixed. After rounding I was subtracting 0.01 which was again giving me the float inaccurate number to 2.3200000000000004. So now I am rounding it again after subtraction. – Anuprit Oct 21 '11 at 21:51
5

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/

alf
  • 8,377
  • 24
  • 45
  • oh! I am getting it. I Keep forgetting the basics! I understand what you said that when the numbers are converted to string the problem is seen. But I think I can see the same value in the database too. Let me verify. Thanks. – Anuprit Oct 20 '11 at 21:10
3

Your problem is just that Floats are not precise:

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

That's not really language specific.

Michael Kohl
  • 66,324
  • 14
  • 138
  • 158
0

Just covert Float to BigDecimal with .to_d to solve your Accuracy Problem

(2.32.to_d * 3.to_d).to_f
=> 6.96
itsnikolay
  • 17,415
  • 4
  • 65
  • 64