Prev: lisp port
Next: Disjoint sets
From: Nicolas Neuss on 23 May 2010 16:03 �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 24 May 2010 06:37 �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 24 May 2010 14:38 �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 24 May 2010 18:10 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 24 May 2010 18:17
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 |