[R] strangely long floating point with write.table()

Mike Miller mbmiller+l at gmail.com
Sat Mar 15 20:54:28 CET 2014


On Sat, 15 Mar 2014, peter dalgaard wrote:

> I don't think so. I think some of your numbers differ sufficiently from 
> numbers with only a few digits to the right of the decimal that 
> write.table needs to write them with increased precision. You didn't 
> read them like that, didn't you? You did some calculations, and then it 
> _looked like_ the results have <= 6 digits after the decimal point?

These have different representations:

1-0.995
2-1.995

write(c(1-0.995, 2-1.995), file="data1.txt", sep="\n")
write.table(c(1-0.995, 2-1.995), file="data2.txt", row.names=F, col.names=F)

$ head -2 data[12].txt
==> data1.txt <==
0.005
0.005

==> data2.txt <==
0.005
0.00499999999999989


> The digits= setting has nothing to do with this, write.table alway does 
> its damndest to avoid loss of precision. This _is_ in help(write.table):
>
>     In almost all cases the conversion of numeric quantities is
>     governed by the option ‘"scipen"’ (see ‘options’), but with the
>     internal equivalent of ‘digits = 15’.  For finer control, use
>     ‘format’ to make a character matrix/data frame, and call
>     ‘write.table’ on that.

Yes!  This was my mistake:  write() not write.table() is controlled by 
options(digits=7).  Repeating the write() command using a different number 
of digits:

> options(digits=15)
> getOption("digits")
[1] 15
> write(c(1-0.995, 2-1.995), file="data1.txt", sep="\n")

$ cat data1.txt
0.005
0.00499999999999989

I don't know why it shows 17 digits and doesn't round to 15, but it is 
showing that the numbers are different, for some reason.

Do you understand why there is a difference between 1-0.995 and 2-1.995 in 
their internal representations?

Mike


More information about the R-help mailing list