From: Þorne on
I am a bit of a math idiot. I have looked at the entries on number
data types in Common Lisp in the Hyperspec but have not really
understood it. I am wondering if there is anything on-line someone
could point me to that would help -- something like an idiot's guide.
The thing that has me specifically thinking about this, because it is
so counter-intuitive is:

(- 343 273.15) => 69.850006

What in general, I am wondering, does one need to do to make this come
out the way someone (like me) would expect?
From: Captain Obvious on
> The thing that has me specifically thinking about this, because it is
> so counter-intuitive is:

> (- 343 273.15) => 69.850006

This is the behaviour of IEEE floating point numbers, it is not in any way
specific to Common Lisp.
Most programming languages use IEEE floating point numbers, and all they
suffer from this kind of inexact results because it is in the very nature of
these floating point numbers.

But Common Lisp also supports exact rational numbers, so you can write:

(- 343 27315/100) => 1397/20

Does this need any explanation?

From: Þorne on
On May 22, 4:19 pm, "Captain Obvious" <udode...(a)users.sourceforge.net>
wrote:
> This is the behaviour of IEEE floating point numbers, it is not in any way
> specific to Common Lisp.
> Most programming languages use IEEE floating point numbers, and all they
> suffer from this kind of inexact results because it is in the very nature of
> these floating point numbers.
>
> But Common Lisp also supports exact rational numbers, so you can write:
>
> (- 343 27315/100) => 1397/20
>
> Does this need any explanation?

Probably. :-) But leaving that aside, my actual practical concern at
the moment is in the possibility of introducing forms of imprecision
that increase each time some running value is subjected to a new
operation. Given unlimited space and time (which I effectively have)
is it valid as a rule of thumb to say, "never use a float when a
rational will do?" If I wanted to write a bunch of mathematical
functions, would the right approach then be to use rationals as
constant values?

273.15, for example, is the difference between degrees Celsius and
Kelvin. Would I be better doing say, (defconstant +c-to-k+ 27315/100)
? -- and then only converting to floats on the final output step back
to the user? -- and then also converting input to rationals even if it
won't increase precession, but because it will avoid type contagion
back to floats? (I'm sure you can tell I am a bit over my head here.)


From: Barry Margolin on
In article
<a3313099-79f1-4187-a7bc-3e08c8eb6ca1(a)u20g2000pru.googlegroups.com>,
�orne <ego111(a)gmail.com> wrote:

> On May 22, 4:19�pm, "Captain Obvious" <udode...(a)users.sourceforge.net>
> wrote:
> > This is the behaviour of IEEE floating point numbers, it is not in any way
> > specific to Common Lisp.
> > Most programming languages use IEEE floating point numbers, and all they
> > suffer from this kind of inexact results because it is in the very nature of
> > these floating point numbers.
> >
> > But Common Lisp also supports exact rational numbers, so you can write:
> >
> > (- 343 27315/100) => 1397/20
> >
> > Does this need any explanation?
>
> Probably. :-) But leaving that aside, my actual practical concern at
> the moment is in the possibility of introducing forms of imprecision
> that increase each time some running value is subjected to a new
> operation. Given unlimited space and time (which I effectively have)
> is it valid as a rule of thumb to say, "never use a float when a
> rational will do?" If I wanted to write a bunch of mathematical
> functions, would the right approach then be to use rationals as
> constant values?'

Generally, yes; that's why CL has rationals. Although if you're doing
trigonometry or logarithms, you're dealing with inherently irrational
calculations -- pi and e must be approximated using floats.

>
> 273.15, for example, is the difference between degrees Celsius and
> Kelvin. Would I be better doing say, (defconstant +c-to-k+ 27315/100)
> ? -- and then only converting to floats on the final output step back
> to the user? -- and then also converting input to rationals even if it
> won't increase precession, but because it will avoid type contagion
> back to floats? (I'm sure you can tell I am a bit over my head here.)

Yes, this is probably the best plan. Although a compromise would be to
use double floats rather than single floats; this will minimize the
error introduced by using floating point.

The ultimate cause of the problem with floating point is that 1/10 can't
be represented exactly in binary floating point; it's a repeating binary
fraction. It's the same reason that calculating 1 / 3 * 3 on a decimal
calculator will result in .99999 rather than 1.

--
Barry Margolin, barmar(a)alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: George Neuner on
On Sat, 22 May 2010 13:27:10 -0700 (PDT), �orne <ego111(a)gmail.com>
wrote:

>I am a bit of a math idiot. I have looked at the entries on number
>data types in Common Lisp in the Hyperspec but have not really
>understood it. I am wondering if there is anything on-line someone
>could point me to that would help -- something like an idiot's guide.
>The thing that has me specifically thinking about this, because it is
>so counter-intuitive is:
>
>(- 343 273.15) => 69.850006
>
>What in general, I am wondering, does one need to do to make this come
>out the way someone (like me) would expect?

Use rationals whenever possible.

And read: David Goldberg, "What Every Computer Scientist Should Know
About Floating Point Arithmetic"
http://dlc.sun.com/pdf/800-7895/800-7895.pdf

George
 |  Next  |  Last
Pages: 1 2 3 4 5 6 7
Prev: lisp port
Next: Disjoint sets