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
Copyright © 2007 David W. Fanning
Last Updated 10 December 2007