# Floating point subtraction question

**URL:** <https://www.ruby-forum.com/t/floating-point-subtraction-question/48969>\
**Category:** Ruby\
**Created:** [November 27, 2005, 11:44pm UTC](https://www.ruby-forum.com/t/floating-point-subtraction-question/48969 "2005-11-27T23:44:32Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![nick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f9ae1b/32.png) [@nick](https://www.ruby-forum.com/u/nick)\
**Post date:** [November 27, 2005, 11:44pm UTC](https://www.ruby-forum.com/t/floating-point-subtraction-question/48969/1 "2005-11-27T23:44:32Z")

</div>

Hi,

I’m a bit confused with some simple floating point arithmetic:

% ruby -e ‘puts “#{(1.2 - 1.0) == 0.2}”’  
false

% ruby -e ‘puts “#{(1.5 - 1.0) == 0.5}”’  
true

I’m sure there’s a perfectly logical reason for this, but i think i’ve  
been staring at it for too long to see what it is.

Can anyone shed some light on this?

Thanks for your help,  
Nick

ps:  
% ruby -v  
ruby 1.8.3 (2005-06-23) [i486-linux]

---

<div class="post-metadata">

**Author:** ![nick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f9ae1b/32.png) [@nick](https://www.ruby-forum.com/u/nick)\
**Post date:** [November 27, 2005, 11:52pm UTC](https://www.ruby-forum.com/t/floating-point-subtraction-question/48969/2 "2005-11-27T23:52:35Z")

</div>

On Nov 27, 2005, at 3:41 PM, Nicholas R. wrote:

> I’m a bit confused with some simple floating point arithmetic:
> 
> % ruby -e ‘puts “#{(1.2 - 1.0) == 0.2}”’  
> false
> 
> % ruby -e ‘puts “#{(1.5 - 1.0) == 0.5}”’  
> true

Slim:~ gavinkistner$ irb  
irb(main):001:0\> 1.2-1.0  
=\> 0.2  
irb(main):002:0\> (1.2-1.0)==0.2  
=\> false  
irb(main):003:0\> “%.31f” % [1.2-1.0]  
=\> “0.1999999999999999555910790149937”  
irb(main):004:0\> “%.31f” % [0.2]  
=\> “0.2000000000000000111022302462516”  
irb(main):005:0\> “%.31f” % [1.2]  
=\> “1.1999999999999999555910790149937”

Because many digits cannot be precisely represented as powers of 2.

For more info, try a plethora of online resources on floating point  
math, such as:

> **[Floating-point arithmetic](https://en.wikipedia.org/wiki/Floating_point#Problems_with_floating-point)**
>
> In computing, floating-point arithmetic (FP) is arithmetic that represents subsets of real numbers using an integer with a fixed precision, called the significand, scaled by an integer exponent of a fixed base.
> Numbers of this form are called floating-point numbers.: 3 : 10 
> For example, 12.345 is a floating-point number in base ten with five digits of precision:
> However, unlike 12.345, 12.3456 is not a floating-point number in base ten with five digits of precision—it needs six digits of pre...

---

<div class="post-metadata">

**Author:** ![nick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f9ae1b/32.png) [@nick](https://www.ruby-forum.com/u/nick)\
**Post date:** [November 28, 2005, 12:08am UTC](https://www.ruby-forum.com/t/floating-point-subtraction-question/48969/3 "2005-11-28T00:08:42Z")

</div>

On Nov 27, 2005, at 5:41 PM, Nicholas R. wrote:

> I’m a bit confused with some simple floating point arithmetic:
> 
> % ruby -e ‘puts “#{(1.2 - 1.0) == 0.2}”’  
> false
> 
> % ruby -e ‘puts “#{(1.5 - 1.0) == 0.5}”’  
> true
> 
> I’m sure there’s a perfectly logical reason for this, but i think i’ve  
> been staring at it for too long to see what it is.

The short answer is that decimal floating point literals can not  
accurately represent the binary floating point values so you get  
all sorts of rounding errors. Take a look at  
[http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html](http://babbage.cs.qc.edu/courses/cs341/IEEE-754.html)

In general it is a mistake to use == to compare floating point values  
because  
of this mismatch. An alternate approach is to ask if the difference  
between two values is less than some small delta:

instead of a == b  
use abs(a - b) \< delta  
for some suitable (small, near zero) value of delta

For all the gory details read “What Every Computer Scientist Should  
Know About Floating-Point”  
[http://docs.sun.com/source/806-3568/ncg\_goldberg.html](http://docs.sun.com/source/806-3568/ncg_goldberg.html)

---

<div class="post-metadata">

**Author:** ![nick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f9ae1b/32.png) [@nick](https://www.ruby-forum.com/u/nick)\
**Post date:** [November 28, 2005, 12:44am UTC](https://www.ruby-forum.com/t/floating-point-subtraction-question/48969/4 "2005-11-28T00:44:56Z")

</div>

John W. Kennedy wrote:

> > ruby 1.8.3 (2005-06-23) [i486-linux]
> 
> where epsilon is some really small number that serves for your purposes  
> as “practically equal”.

> (IBM mainframes have hardware to handle decimal fractions directly, and  
> a very few languages – COBOL, RPG, PL/I, and Ada '95 come to mind –  
> have the extra features to make use of it. Some other languages, Java,  
> for example, include libraries to help you do the “calculate in cents”  
> trick. Ruby, however, does not at present include either facility.)

BASIC on the 8-bit Atari used binary-coded decimal.

---

<div class="post-metadata">

**Author:** ![nick](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/f9ae1b/32.png) [@nick](https://www.ruby-forum.com/u/nick)\
**Post date:** [November 28, 2005, 12:20am UTC](https://www.ruby-forum.com/t/floating-point-subtraction-question/48969/5 "2005-11-28T00:20:47Z")

</div>

Nicholas R. wrote:

> I’m sure there’s a perfectly logical reason for this, but i think i’ve  
> been staring at it for too long to see what it is.
> 
> Can anyone shed some light on this?
> 
> Thanks for your help,  
> Nick
> 
> ps:  
> % ruby -v  
> ruby 1.8.3 (2005-06-23) [i486-linux]

This has nothing to do with Ruby, itself, but is a basic characteristic  
of nearly all languages and nearly all computers.

Remember how you can’t make 1/3 a decimal fraction, because it’s  
0.3333333333333 – carried out to infinity, so that if you add 1/3 + 1/3

- 1/3, you get 0.9999999 – carried out to infinity, instead of 1.0?  
Well, computers (almost always) use binary fractions, and you can’t make  
1/10 a binary fraction, because it comes out as 0.000110011001100110011  
– carried out to infinity, and so you get the same kind of problem.

If you are doing science or engineering, it doesn’t matter, because  
things in the real world don’t come out as neat decimal fractions,  
anyway. But you do want to avoid checking for equality. Instead of

```
x==y

```

look for

```
abs(x-y)<epsilon

```

where epsilon is some really small number that serves for your purposes  
as “practically equal”.

If, on the other hand, you are working with money, don’t use fractions.  
Calculate in cents (or centimes, or new pence, or whatever), and only  
divide by 100 (or whatever) at the last moment, when you’re printing  
your results.

(IBM mainframes have hardware to handle decimal fractions directly, and  
a very few languages – COBOL, RPG, PL/I, and Ada '95 come to mind –  
have the extra features to make use of it. Some other languages, Java,  
for example, include libraries to help you do the “calculate in cents”  
trick. Ruby, however, does not at present include either facility.)
