Zack Weinberg
2007-May-22 07:13 UTC
[Rd] R 2.5.0 refuses to print enough digits to recover exact floating point values
I have noticed that in R 2.5.0, no method of textual output will print a "double" mode quantity with more than 15 digits after the decimal point. From the help page (?print.default) it appears that this is intentional, since digits after the fifteenth may be uncertain. However, fifteen digits after the decimal point are not enough to represent all the values that an IEEE-double can take. (You need one more.) This means it is now impossible to write out data in textual format (e.g. in order to manipulate it with another program) and read back in exactly the same values. Some analyses are sensitive to this sort of extra rounding, especially if it happens repeatedly. I'd really appreciate some way of forcing R to print enough digits to represent every possible IEEE double value. I would also argue that this should be the default behavior of dump(), write.table() and friends, and save(...,ascii=TRUE), to prevent data loss. [Tangentially, support for C99 hexadecimal notation for floating point values in input and output would also be nice, but wouldn't help much for interoperability, since very few programs understand it.] zw
Uwe Ligges
2007-May-22 10:10 UTC
[Rd] R 2.5.0 refuses to print enough digits to recover exact floating point values
Zack Weinberg wrote:> I have noticed that in R 2.5.0, no method of textual output will print > a "double" mode quantity with more than 15 digits after the decimal > point. From the help page (?print.default) it appears that this is > intentional, since digits after the fifteenth may be uncertain. > However, fifteen digits after the decimal point are not enough to > represent all the values that an IEEE-double can take. (You need one > more.) This means it is now impossible to write out data in textual > format (e.g. in order to manipulate it with another program) and read > back in exactly the same values. Some analyses are sensitive to this > sort of extra rounding, especially if it happens repeatedly. > > I'd really appreciate some way of forcing R to print enough digits to > represent every possible IEEE double value. I would also argue that > this should be the default behavior of dump(), write.table() and > friends, and save(...,ascii=TRUE), to prevent data loss.Example: formatC(exp(1), digits=100, width=-1) Uwe Ligges> [Tangentially, support for C99 hexadecimal notation for floating point > values in input and output would also be nice, but wouldn't help much > for interoperability, since very few programs understand it.] > > zw > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel
Petr Savicky
2007-May-23 17:22 UTC
[Rd] R 2.5.0 refuses to print enough digits to recover exact floating point values
This is an addition to my previous message. 16 digits are indeed not sufficient to represent a double value exactly. The next table is calculated in bc calculator. It shows that if we restrict (or round) double values to 16 decadic digits then from 4 to 5 consecutive distinct double values get the same 16 digit decadic code. 1.234567890123456 a 16-digit number for comparison 1.0000000000000000000000000000 1 + 0*2^(-52) 1.0000000000000002220446049250 1 + 1*2^(-52) 1.0000000000000004440892098500 1 + 2*2^(-52) 1.0000000000000006661338147750 1 + 3*2^(-52) 1.0000000000000008881784197001 1 + 4*2^(-52) 1.0000000000000011102230246251 1 + 5*2^(-52) 1.0000000000000013322676295501 1 + 6*2^(-52) 1.0000000000000015543122344752 1 + 7*2^(-52) 1.0000000000000017763568394002 1 + 8*2^(-52) 1.0000000000000019984014443252 1 + 9*2^(-52) 1.0000000000000022204460492503 1 + 10*2^(-52) 1.0000000000000024424906541753 1 + 11*2^(-52) 1.0000000000000026645352591003 1 + 12*2^(-52) 1.0000000000000028865798640254 1 + 13*2^(-52) 1.0000000000000031086244689504 1 + 14*2^(-52) 1.0000000000000033306690738754 1 + 15*2^(-52) 1.0000000000000035527136788005 1 + 16*2^(-52) 1.0000000000000037747582837255 1 + 17*2^(-52) 1.0000000000000039968028886505 1 + 18*2^(-52) 1.0000000000000042188474935755 1 + 19*2^(-52) Petr.