On Sat, 15 Mar 2014, Rui Barradas wrote:
I haven't followed this thread since its start but I think you now have
a case for FAQ 7.31. See inline below.
Try
(1-0.995) - 0.005
[1] 4.336809e-18
(2-1.995) - 0.005
[1] -1.066855e-16
Hope this helps,
Yes, that does show the problem well, but it isn't an issue of equality of
numbers, it's an issue of what to print. The problem is that a number
like .005 may round down to three digits if we only look at 15 digits, but
it might not round down if we look at 17 digits. When the machine
precision is 2^-52 = 2.22e-16, why are we looking at 17 digits?
We don't want to print 14 digits of nonsense, right?
At least with write() we have some control, but we don't have that control
with write.table().
But even with write(), I find the behavior a little unusual:
> options(digits=15)
> write(1-0.995, file="/dev/stdout")
0.0050000000000000044
1234567890123456789 <- I added this
> write(2-1.995, file="/dev/stdout")
0.0049999999999998934
1234567890123456789 <- I added this
If we round at the 15th digit we should have 0.005 followed by nothing but
zeros, so why doesn't that happen? Why does write() display 19 digits
when options(digits=15) is set?
A lot of short decimal numbers don't have exact binary expansions, so this
is going to happen all the time. I think we should have an easy way to
preserve the short numbers as they are without having to present them as
17 digits long. This also happens erratically, for the reason you show
above -- write.table() uses a level of precision that teeters on the edge
of machine precision, sometimes falling in one direction, sometimes in the
other. The result is annoyingly haphazard.
The cause of the problem is like that of the equality problem -- internal
binary representations -- but the equality problem can't really be solved
(well, one could use abs(diff)<num, if that worked). This problem is not
hard to solve. In fact, the write() command with options(digits) is
supposed to solve this. I guess it does solve it, within the limited uses
to which write() is usually applied, but it doesn't do what I would expect
in terms of number of digits. Don't we want similar functionality for
write.table(), and related fuctions? Or maybe just reduce the precision
of write.table() by some small amount so that machine precision isn't
constantly causing annoying output?
Thanks.
Mike
--
Michael B. Miller, Ph.D.
Minnesota Center for Twin and Family Research
Department of Psychology
University of Minnesota
http://scholar.google.com/citations?user=EV_phq4AAAAJ
______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.