Fanning Software Consulting

Double Precision Numbers in IDL

QUESTION: I thought double precision numbers were suppose to be, like, really accurate or something. But check this out:

   IDL> n = Double(9999.9)
   IDL> Print, n, Format='(F20.10)'
     9999.9003906250

That ain't right, man! How am I gonna get my degree if my computer can't do any better than this!? Professor Malarkey is gonna eat my lunch.

ANSWER: Oh, hang on a minute. Take a deep breath. Relax. The sky is not falling. There are just a couple of things you need to know before you finish your degree.

First, it would be extremely helpful if you understood how numbers are represented on a computer. With that understanding, you will realize that floating point numbers can be represented with approximately seven decimal places of significance, whereas double precision numbers can be represented with approximately 14 decimal places of significance. The number you printed out above starts to vary in the eighth decimal place of significance. Thus, we might conclude that it is a floating point number, just on the basis of decimal significance.

But, you say, I expressly made it a double precision number. Yes, but what you made a double precision number, was a floaing point number with just seven decimal places of significance. So your result is prefectly reasonable. One might even say "accurate".

What you probably wanted to do, was make the number 9999.9 a double precision number (with 14 decimal places of significance) from the start. To do this, you must place a "D" at the end of the number. This is probably what you had in mind:

   IDL> n = 9999.9D
   IDL> Print, n, Format='(F20.10)'
     9999.9000000000

And what you should also realize (and thanks to Reimar Bauer for pointing this out in the IDL newsgroup), is that this also appplies to arrays. For example, some people, when they are creating a double precision array, will assign a "D" to the first value in the array, thinking that this will make all the values in the array double precision. It does do this, but in the manner of the first example above, not the second. Consider this:

 
   IDL> a = [10.0D, 20.5, 9999.9]
   IDL> Help, a
        A               DOUBLE    = Array[3]
   IDL> Print, a, Format='(F20.10)'
       10.0000000000
       20.5000000000
     9999.9003906250

Notice in this example, that the value 20.5 can be represented in floating point notation in a way that could confuse you as to the real accuracy of the numbers in your array!

The proper way to write this array is like this:

 
   IDL> a = [10.0D, 20.5D, 9999.9D]
   IDL> Help, a
        A               DOUBLE    = Array[3]
   IDL> Print, a, Format='(F20.10)'
       10.0000000000
       20.5000000000
     9999.9000000000

And your caution should even extend to using IDL's routine Make_Array. So, for example, this:

   IDL> array = Make_Array(3, Value=9999.9, /Double)
   IDL> Print, array, Format='(F20.10)'
     9999.9003906250
     9999.9003906250
     9999.9003906250

is different from this:

   IDL> array = Make_Array(3, Value=9999.9D, /Double)
   IDL> Print, array, Format='(F20.10)'
     9999.9000000000
     9999.9000000000
     9999.9000000000

With this in mind, you should have no trouble getting your degree in the required 10 years.

Google
 
Web Coyote's Guide to IDL Programming