From: Nicolas Neuss on
�orne <ego111(a)gmail.com> writes:

> 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?

By default 273.15 is a floating point number with only about 7 digits of
accuracy. I usually need more and therefore have

(setq *READ-DEFAULT-FLOAT-FORMAT* 'double-float)

in my initialization file.

Nicolas

P.S.: Contrary to other recommendations I would not use 27315/100 here,
because calculations in physics usually involve inexact constants and
inexact data.
From: Norbert_Paul on
�orne 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?

What would you expect to get from, say,

343
-273 1/3
---------
HERE.??????????

in decimal expansion. Note that your ".15" is 15/100 = 3/20 has an
infinite binary expansion:

decimal (3/20) is in binary (11/10100)

11 : 10100 = try it yourself.

Norbert
From: Thomas A. Russ on
�orne <ego111(a)gmail.com> writes:

> 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?

Yes, that will give you the most precision. And the conversion is
pretty easy, since you can do it entirely using the FORMAT directive

(format t "~F" 1/3)

although that will have the issue of using (by default) SINGLE-FLOAT
format rather than DOUBLE-FLOAT. You can change that by explicitly
converting using the FLOAT function with the optional second argument

(format t "~F" (float 1/3 0d0))

or using COERCE

(format t "~F" (coerce 1/3 'double-float))

> -- 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. There are actually two different functions that will convert
floating point to rational values: RATIONAL and RATIONALIZE. The first
one will give you an exact rational for the floating point value. You
probably don't want that. The second one gives you the "nicest"
rational whose floating point representation is the given float. The
reason this makes a difference has to do with repeating fractions. As
an example, try

(rational (/ 1.0 3.0)) => 11184811/33554432
(rationalize (/ 1.0 3.0)) => 1/3

(rational (/ 1.0d0 3.0d0)) => 6004799503160661/18014398509481984
(rationalize (/ 1.0d0 3.0d0)) => 1/3

This is related to the issue of not having an exact binary
representation for all of the rational numbers.

--
Thomas A. Russ, USC/Information Sciences Institute
From: Günther Thomsen on
On May 23, 6:22 am, p...(a)informatimago.com (Pascal J. Bourguignon)
wrote:
> and on the hand, why would you write:
>
>     2.5
>  *  4.00
> -----------------
>    10.000
>
> and not just 10.
>
> Notice that the expectation here is that:
>       2.5 * 4.00  = 10.000
> but:
>       2.5 * 4.000 = 10.0000
> which is quite a different result.
>
Would you mind explaining where the additional precision comes from?


> If you are working with physical quantities, the expectation is to
> preserve the precision.  
If you want to be correct, you use error propagation. For high school
math you might get away with "significance arithmetic"
http://en.wikipedia.org/wiki/Significance_arithmetic
From: Günther Thomsen on
On May 22, 3:19 pm, "Captain Obvious" <udode...(a)users.sourceforge.net>
wrote:
>  > 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.

I don't think it hurts to throw in the reference to "What Every
Computer Scientist Should Know About Floating-Point Arithmetic" text:
http://docs.sun.com/source/806-3568/ncg_goldberg.html
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7
Prev: lisp port
Next: Disjoint sets