Prev: lisp port
Next: Disjoint sets
From: Þorne on 22 May 2010 16:27 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 22 May 2010 18:19 > 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 22 May 2010 19:13 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 22 May 2010 19:46 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 23 May 2010 11:38
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 |