Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Unexpected subtraction behaviour

51 views
Skip to first unread message

djpeebz

unread,
Nov 27, 2011, 5:09:26 AM11/27/11
to
Dear list,

I'm getting some unexpected behaviour with sbcl (and also CLISP so I guess it's common) and I was wondering if anyone can explain it. If I enter (- 0.5 0.3) I get

0.19999999

but when I enter (- 0.5 0.2) I get

0.3

Does anyone know why this is and how I can convert the first example to 0.2?

Cheers,

David

Raja Naresh

unread,
Nov 27, 2011, 5:40:59 AM11/27/11
to
I am curious about this behavior as well. I found this after
searching. Didn't delve much into the paper though. kurtstephens.com/
files/p372-steele.pdf

Tim Bradshaw

unread,
Nov 27, 2011, 6:06:58 AM11/27/11
to
djpeebz <djp...@gmail.com> wrote:
> Dear list,
>
> I'm getting some unexpected behaviour with sbcl (and also CLISP so I
> guess it's common) and I was wondering if anyone can explain it. If I
> enter (- 0.5 0.3) I get
>
> 0.19999999
>

look up "floating point" on a search engine

Pascal J. Bourguignon

unread,
Nov 27, 2011, 8:34:04 AM11/27/11
to
djpeebz <djp...@gmail.com> writes:

> I'm getting some unexpected behaviour with sbcl (and also CLISP so I
> guess it's common) and I was wondering if anyone can explain it. If I
> enter (- 0.5 0.3) I get
> [...]
> Does anyone know why this is and how I can convert the first example to 0.2?

http://www.exploringbinary.com/the-four-stages-of-floating-point-competence/

What Every Computer Scientist Should Know About Floating-Point Arithmetic
http://docs-pdf.sun.com/800-7895/800-7895.pdf
http://portal.acm.org/citation.cfm?id=103163
http://focus.hut.fi/docs/WorkShop/common/ug/goldberg1.doc.html


--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.

Norbert_Paul

unread,
Nov 27, 2011, 10:55:20 AM11/27/11
to
It is funny that this type of question always occurss here.
There is no binary floating point number of value 0.2 (which is 1/5)
just as no finite decimal number of value 1/3 exists.

Just try to divide 1:5 in /binary/

1.00000 : 101 = <do it yourself>

and you will see what I mean.

Norbert

djpeebz

unread,
Nov 27, 2011, 11:10:46 AM11/27/11
to
Thanks for all your comments and suggestions. I immediately assumed it was a particular lisp representation issue rather than a broader floating point one. I have now moved from a state of unconscious incompetence to one of conscious incompetence :-)

Cheers,

David

William D Clinger

unread,
Nov 27, 2011, 11:25:09 AM11/27/11
to
Norbert_Paul wrote:
> It is funny that this type of question always occurss here.

People who use read/eval/print loops are more likely
to discover this sort of thing for themselves than those
who use a batch programming paradigm.

Will

Joshua Taylor

unread,
Nov 27, 2011, 12:08:42 PM11/27/11
to
One of the nice things that Common Lisp gives you, though, is a rational
data type, so you can actually do a whole lot of the arithmetic without
losing anything to machine representation issues. You might have had a
specific reason for using 0.5 and 0.2 in your original example, but if
you really mean 5/10 and 2/10, you can simply do:

CL-USER 1 > (- 5/10 2/10)
3/10

CL-USER 2 > (- 5/10 3/10)
1/5

This may or may not be appropriate, depending on what you're doing, but
I've found that working with rationals is often preferable (for my own
use, YMMV).

//JT

Scott Burson

unread,
Nov 27, 2011, 1:17:16 PM11/27/11
to
On Nov 27, 9:08 am, Joshua Taylor <tay...@cs.rpi.edu> wrote:
>
> This may or may not be appropriate, depending on what you're doing, but
> I've found that working with rationals is often preferable (for my own
> use, YMMV).

Yes, rational arithmetic is one of the underappreciated gems of Common
Lisp.

One of its uses is to obtain exact representations of decimal
fractions:

> (/ (round 3.1415 .01) 100)
157/50
> (float *)
3.14

If you ever find yourself wishing CL had decimal arithmetic, use
rationals. (Not that that's their only use.)

-- Scott

Zach Beane

unread,
Nov 27, 2011, 2:27:12 PM11/27/11
to
wu-decimal is a handy, Quicklisp-installable library that includes a #$
reader macro and some tools for parsing and printing rationals as
decimals. http://wukix.com/lisp-decimals has the scoop.

I've used it recently instead of rolling my own stuff, and it was quite
handy.

Zach

Norbert_Paul

unread,
Nov 27, 2011, 5:35:26 PM11/27/11
to
Joshua Taylor wrote:
> One of the nice things that Common Lisp gives you, though, is a rational
> data type, so you can actually do a whole lot of the arithmetic without
> losing anything to machine representation issues.
Yeah. But when you solve lots of linear equation systems with
rationals you can easily run out of memory.

At least that was one of my first lessions I had to learn after having
switched from AutoLisp to CL :) .

Antony

unread,
Nov 28, 2011, 9:40:19 AM11/28/11
to
On 11/27/2011 11:27 AM, Zach Beane wrote:
> wu-decimal is a handy, Quicklisp-installable library that includes a #$
> reader macro and some tools for parsing and printing rationals as
> decimals. http://wukix.com/lisp-decimals has the scoop.
>
+1

It's a very small piece of code and I feel well worth looking at for
any newbie to learn a couple of things.

BTW, the only 'standard' languages I know of that provide for fixed
point decimal types and arithmetic are
Cobol and <your favorite rdbms>+sql

-Antony

Alberto Riva

unread,
Nov 28, 2011, 2:11:41 PM11/28/11
to
Note that, given enough 9s, there is no difference between 0.2 and
0.199999999999.... They are the same number.

Alberto

Antti J Ylikoski

unread,
Nov 29, 2011, 12:15:11 AM11/29/11
to
At least with the combination of GNU EMACS, SLIME and SBCL -- which is
what I'm using -- you can correct the cosmetic problem by using
double-precision floats, as follows:

; SLIME 2011-06-21
CL-USER> (- 0.5 0.2)
0.3
CL-USER> (- 0.5 0.3)
0.19999999
CL-USER> (- 0.5d0 0.3d0)
0.2d0
CL-USER> (- 0.5d0 0.2d0)
0.3d0
CL-USER>

This does not fix the inherent behaviour of floating-point arithmetic of
course, but it is a remedy for the aesthetic problem......

Cheers, Andy

Norbert_Paul

unread,
Nov 29, 2011, 4:09:01 AM11/29/11
to
Alberto Riva wrote:
> Note that, given enough 9s, there is no difference between 0.2 and
> 0.199999999999.... They are the same number.

Cool!
How do you manage to store so many 9s on your computer?
Doesn't it have finite memory?
:)

Espen Vestre

unread,
Nov 29, 2011, 4:13:58 AM11/29/11
to
Norbert_Paul <norbertpau...@yahoo.com> writes:

> Cool!
> How do you manage to store so many 9s on your computer?
> Doesn't it have finite memory?

Any repeating decimal is a fraction, so the answer in Common Lisp should
be obvious ;-)
--
(espen)

Alex Mizrahi

unread,
Nov 29, 2011, 4:54:54 PM11/29/11
to
> Cool!
> How do you manage to store so many 9s on your computer?
> Doesn't it have finite memory?
> :)

#1=(9 . #1#)

Norbert_Paul

unread,
Nov 30, 2011, 5:36:50 AM11/30/11
to
:)
Of course, every two 9s are equal.
So one 9 if enough 9s for Alberto, too.

Alberto Riva

unread,
Nov 30, 2011, 3:14:45 PM11/30/11
to
Right :) And I never said I'm storing them on my computer, after all...
I just said "given enough 9s" :)

Alberto

0 new messages