Reading Double Precision Values<

QUESTION: I am trying to read some double precision variables from a file, using a format statement, but the variables seem to have single precision values when I use them. My ASCII data file, named test.dat, consists of a number of lines that look like this:

     48883   149.55579541    12.44483936

The code I use to read the data looks like this:

   nlines = File_Lines('test.dat')
   fileFormat = '(2x, I5, 2X, D13.8, 2X, D13.8)'
   OpenR, lun, 'test.dat', /Get_Lun
   data = Make_Array(3, nlines, /DOUBLE)
   FOR j=0,nlines-1 DO BEGIN
      ReadF, lun, num, ra, dec, FORMAT=fileFormat 
      data[0,j] = num
      data[1,j] = ra
      data[2,j] = dec
    ENDFOR
    Free_Lun, lun

But, when I print the data, I get something like this:

   IDL> Print, data[*,0], FORMAT=fileFormat 
    48883   149.55580139    12.44483948

As you can see, that is different from what I read in, and if I am not mistaken, it is only preserving single-precision accuracy. What is going on?

ANSWER: Well, this is most interesting. There is a mismatch between your variables (num, ra, and dec) and your format statement. In other words, the variables num, ra and dec, since they are undeclared in the program, are treated as default floating point variables. In the case of the variables ra and dec, your format statement is going to direct IDL to read those variable from the file as doubles. But, the “rules” of IDL input state that IDL will try, whenever possible, to convert whatever it reads into the type of data variable that will hold the value of the variable. Here, IDL reads the data correctly as doubles, but since you provided floating point variables, the data is transferred to the variables as floats.The solution to this problem is to declare the variables on your ReadF statement to be type you want to hold the data. That is, in the case of ra and dec, you want to declare these as doubles. For example, you code should look more like this:

   nlines = File_Lines('test.dat')
   fileFormat = ('2x, I5, 2X, D13.8, 2X, D13.8)'
   OpenR, lun, 'test.dat', /Get_Lun
   data = Make_Array(3, nlines, /DOUBLE)
   num = 0L
   ra = 0.0D
   dec = 0.0D
   FOR j=0,nlines-1 DO BEGIN
      ReadF, lun, num, ra, dec, FORMAT=fileFormat 
      data[0,j] = num
      data[1,j] = ra
      data[2,j] = dec
    ENDFOR
    Free_Lun, lun

Of course, there is no reason to read the data line by line in this case, anyway. A much better way to read the data might have been like this:

   nlines = File_Lines('test.dat')
   fileFormat = ('2x, I5, 2X, D13.8, 2X, D13.8)'
   OpenR, lun, 'test.dat', /Get_Lun
   data = Replicate({num:0L, ra:0.0D, dec:0.0D}, nlines)
   ReadF, lun, data, FORMAT=fileFormat 
   Free_Lun, lun

Google
 
Web Coyote's Guide to IDL Programming