[R] strangely long floating point with write.table()
Mike Miller
mbmiller+l at gmail.com
Sat Mar 15 21:45:26 CET 2014
Having just learned a few tricks from you guys, this might be the neatest
way to show the issue:
> write.table(c(1-0.995, 2-1.995), row.names=F, col.names=F)
0.005
0.00499999999999989
options(digits) only works with write(), and not with write.table():
> options(digits=7)
> write(c(1-0.995, 2-1.995), file="/dev/stdout", sep="\n")
0.005
0.005
> options(digits=15)
> write(c(1-0.995, 2-1.995), file="/dev/stdout", sep="\n")
0.005
0.00499999999999989
It seems strangely inconsistent to me:
> options(digits=15)
> write(2-1.995, file="/dev/stdout")
0.00499999999999989
> write(2-1-0.995, file="/dev/stdout")
0.005
> write(2-0.995-1, file="/dev/stdout")
0.00499999999999989
So the order matters, but then why don't either of these give more digits?
> write(2-0.995, file="/dev/stdout")
1.005
> write(0.995-1, file="/dev/stdout")
-0.005
Thus,
2-0.995-1 is long, but
2-0.995 is short, and
0.995-1 is short.
That doesn't seem right to me.
Now I see the problem better: If I go to 17 digits, then I return to
consistency:
> options(digits=15)
> write(1-0.995, file="/dev/stdout")
0.0050000000000000044
> write(2-1.995, file="/dev/stdout")
0.0049999999999998934
> write(2-1-0.995, file="/dev/stdout")
0.0050000000000000044
> write(2-0.995-1, file="/dev/stdout")
0.0049999999999998934
> write(2-0.995, file="/dev/stdout")
1.0049999999999999
> write(0.995-1, file="/dev/stdout")
-0.0050000000000000044
The problem was that some of the numbers round at 15 digits but not at 17
digits, or something close to that. I'm sure this has to do with the
machine precision:
> .Machine$double.eps
[1] 2.2204460492503131e-16
I thing it is an undesirable feature that write.table() has to try to use
so many digits -- all the way out to eps -- because it causes these kinds
of inconsistencies. Is there no way to get it to put out numbers in the
obviously desirable way without having to write format statements?
Mike
More information about the R-help
mailing list