I think Robin knows about FAQ 7.31/floating point (author of 'Brobdingnag', among other numerical packages). I agree that this is surprising (to me). To reframe this question: is there way to get an *exact* ASCII representation of a numeric value (i.e., guaranteeing the restored value is identical() to the original) ? .deparseOpts has ?"digits17"?: Real and finite complex numbers are output using format ?"%.17g"? which may give more precision than the default (but the output will depend on the platform and there may be loss of precision when read back). ... but this still doesn't guarantee that all precision is kept. Maybe saveRDS(x,textConnection("out","w"),ascii=TRUE) identical(x,as.numeric(out[length(out)])) ## TRUE ? On 2020-02-29 2:42 a.m., Rui Barradas wrote:> Hello, > > FAQ 7.31 > > See also this StackOverflow post: > > https://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal > > Hope this helps, > > Rui Barradas > > ?s 00:08 de 29/02/20, robin hankin escreveu: >> My interpretation of dput.Rd is that dput() gives an exact ASCII form >> of the internal representation of an R object.? But: >> >> ? rhankin at cuttlefish:~ $ R --version >> R version 3.6.2 (2019-12-12) -- "Dark and Stormy Night" >> Copyright (C) 2019 The R Foundation for Statistical Computing >> Platform: x86_64-pc-linux-gnu (64-bit) >> >> [snip] >> >> rhankin at cuttlefish:~ $ R --vanilla --quiet >>> x <- sum(dbinom(0:20,20,0.35)) >>> dput(x) >> 1 >>> x-1 >> [1] -4.440892e-16 >>> >>> x==1 >> [1] FALSE >>> >> >> So, dput(x) gives 1, but x is not equal to 1.? Can anyone advise? >> >> ______________________________________________ >> R-devel at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel
On 29/02/2020 4:19 a.m., Ben Bolker wrote:> > I think Robin knows about FAQ 7.31/floating point (author of > 'Brobdingnag', among other numerical packages). I agree that this is > surprising (to me). > > To reframe this question: is there way to get an *exact* ASCII > representation of a numeric value (i.e., guaranteeing the restored value > is identical() to the original) ? > > .deparseOpts has > > ?"digits17"?: Real and finite complex numbers are output using > format ?"%.17g"? which may give more precision than the > default (but the output will depend on the platform and there > may be loss of precision when read back). > > ... but this still doesn't guarantee that all precision is kept."Using control = c("all", "hexNumeric") comes closest to making deparse() an inverse of parse(), as representing double and complex numbers as decimals may well not be exact. However, not all objects are deparse-able even with this option. A warning will be issued if the function recognizes that it is being asked to do the impossible."> > Maybe > > saveRDS(x,textConnection("out","w"),ascii=TRUE) > identical(x,as.numeric(out[length(out)])) ## TRUE > > ? > > > > > On 2020-02-29 2:42 a.m., Rui Barradas wrote: >> Hello, >> >> FAQ 7.31 >> >> See also this StackOverflow post: >> >> https://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal >> >> Hope this helps, >> >> Rui Barradas >> >> ?s 00:08 de 29/02/20, robin hankin escreveu: >>> My interpretation of dput.Rd is that dput() gives an exact ASCII form >>> of the internal representation of an R object.? But: >>> >>> ? rhankin at cuttlefish:~ $ R --version >>> R version 3.6.2 (2019-12-12) -- "Dark and Stormy Night" >>> Copyright (C) 2019 The R Foundation for Statistical Computing >>> Platform: x86_64-pc-linux-gnu (64-bit) >>> >>> [snip] >>> >>> rhankin at cuttlefish:~ $ R --vanilla --quiet >>>> x <- sum(dbinom(0:20,20,0.35)) >>>> dput(x) >>> 1 >>>> x-1 >>> [1] -4.440892e-16 >>>> >>>> x==1 >>> [1] FALSE >>>> >>> >>> So, dput(x) gives 1, but x is not equal to 1.? Can anyone advise? >>> >>> ______________________________________________ >>> R-devel at r-project.org mailing list >>> https://stat.ethz.ch/mailman/listinfo/r-devel >>> >> >> ______________________________________________ >> R-devel at r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
Thanks guys, I guess I should have referred to FAQ 7.31 (which I am indeed very familiar with) to avoid misunderstanding. I have always used dput() to clarify 7.31-type issues. The description in ?dput implies [to me at any rate] that there will be no floating-point roundoff in its output. I hadn't realised that 'deparsing' as discussed in dput.Rd includes precision roundoff issues. I guess the question I should have asked is close to Ben's: "How to force dput() to return an exact representation of a floating point number?". Duncan's reply is the insight I was missing: exact decimal representation of a double might not be possible (this had not occurred to me). Also, Duncan's suggestion of control = c("all", "hexNumeric") looks good and I will experiment with this. Best wishes Robin On Sun, Mar 1, 2020 at 6:22 AM Duncan Murdoch <murdoch.duncan at gmail.com> wrote:> > On 29/02/2020 4:19 a.m., Ben Bolker wrote: > > > > I think Robin knows about FAQ 7.31/floating point (author of > > 'Brobdingnag', among other numerical packages). I agree that this is > > surprising (to me). > > > > To reframe this question: is there way to get an *exact* ASCII > > representation of a numeric value (i.e., guaranteeing the restored value > > is identical() to the original) ? > > > > .deparseOpts has > > > > ?"digits17"?: Real and finite complex numbers are output using > > format ?"%.17g"? which may give more precision than the > > default (but the output will depend on the platform and there > > may be loss of precision when read back). > > > > ... but this still doesn't guarantee that all precision is kept. > > "Using control = c("all", "hexNumeric") comes closest to making > deparse() an inverse of parse(), as representing double and complex > numbers as decimals may well not be exact. However, not all objects are > deparse-able even with this option. A warning will be issued if the > function recognizes that it is being asked to do the impossible." > > > > > Maybe > > > > saveRDS(x,textConnection("out","w"),ascii=TRUE) > > identical(x,as.numeric(out[length(out)])) ## TRUE > > > > ? > > > > > > > > > > On 2020-02-29 2:42 a.m., Rui Barradas wrote: > >> Hello, > >> > >> FAQ 7.31 > >> > >> See also this StackOverflow post: > >> > >> https://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal > >> > >> Hope this helps, > >> > >> Rui Barradas > >> > >> ?s 00:08 de 29/02/20, robin hankin escreveu: > >>> My interpretation of dput.Rd is that dput() gives an exact ASCII form > >>> of the internal representation of an R object. But: > >>> > >>> rhankin at cuttlefish:~ $ R --version > >>> R version 3.6.2 (2019-12-12) -- "Dark and Stormy Night" > >>> Copyright (C) 2019 The R Foundation for Statistical Computing > >>> Platform: x86_64-pc-linux-gnu (64-bit) > >>> > >>> [snip] > >>> > >>> rhankin at cuttlefish:~ $ R --vanilla --quiet > >>>> x <- sum(dbinom(0:20,20,0.35)) > >>>> dput(x) > >>> 1 > >>>> x-1 > >>> [1] -4.440892e-16 > >>>> > >>>> x==1 > >>> [1] FALSE > >>>> > >>> > >>> So, dput(x) gives 1, but x is not equal to 1. Can anyone advise? > >>> > >>> ______________________________________________ > >>> R-devel at r-project.org mailing list > >>> https://stat.ethz.ch/mailman/listinfo/r-devel > >>> > >> > >> ______________________________________________ > >> R-devel at r-project.org mailing list > >> https://stat.ethz.ch/mailman/listinfo/r-devel > > > > ______________________________________________ > > R-devel at r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > > > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel
Ben, I'll edit and split your question just a little. 1) "Is there a way to get an *exact* ASCII representation of a double-precision value?" 2) "Is there a way to get round-trip behavior, i.e. to make sure that the value, when converted back to double, is identical() to the original" The hexNumeric idea mentioned by Duncan is a positive answer to the first question. It's a little hard to grok at first, but it is fully precise and represents exactly a 64-bit double. And since it is exact it converts back identically. But there is another way to get round-trip behavior. There is a set of routines called dtoa that, when given an IEEE double, produce the shortest sequence of base 10 digits that will map back to the double. There may be some rounding when producing these digits, but of all the digit sequences that would map back to the input x, these routines produce the shortest such. A link to the original routines is here: http://www.netlib.org/fp/dtoa.c and some searching will turn up variants of this code in newer guises. A good question to ask: for all finite doubles, what is the length of the longest digit sequence required? I believe 17 digits is the max digits required. It may be 18, but I doubt it. I don't have an example at hand and I spent some time looking when working with these routines. Oh, BTW, trailing or leading zeros do not count toward the length of the digit sequence. -Steve On Sat, Feb 29, 2020 at 4:21 AM Ben Bolker <bbolker at gmail.com> wrote:> > I think Robin knows about FAQ 7.31/floating point (author of > 'Brobdingnag', among other numerical packages). I agree that this is > surprising (to me). > > To reframe this question: is there way to get an *exact* ASCII > representation of a numeric value (i.e., guaranteeing the restored value > is identical() to the original) ? > > .deparseOpts has > > ?"digits17"?: Real and finite complex numbers are output using > format ?"%.17g"? which may give more precision than the > default (but the output will depend on the platform and there > may be loss of precision when read back). > > ... but this still doesn't guarantee that all precision is kept. > > Maybe > > saveRDS(x,textConnection("out","w"),ascii=TRUE) > identical(x,as.numeric(out[length(out)])) ## TRUE > > ? > > > > > On 2020-02-29 2:42 a.m., Rui Barradas wrote: > > Hello, > > > > FAQ 7.31 > > > > See also this StackOverflow post: > > > > > https://stackoverflow.com/questions/9508518/why-are-these-numbers-not-equal > > > > Hope this helps, > > > > Rui Barradas > > > > ?s 00:08 de 29/02/20, robin hankin escreveu: > >> My interpretation of dput.Rd is that dput() gives an exact ASCII form > >> of the internal representation of an R object. But: > >> > >> rhankin at cuttlefish:~ $ R --version > >> R version 3.6.2 (2019-12-12) -- "Dark and Stormy Night" > >> Copyright (C) 2019 The R Foundation for Statistical Computing > >> Platform: x86_64-pc-linux-gnu (64-bit) > >> > >> [snip] > >> > >> rhankin at cuttlefish:~ $ R --vanilla --quiet > >>> x <- sum(dbinom(0:20,20,0.35)) > >>> dput(x) > >> 1 > >>> x-1 > >> [1] -4.440892e-16 > >>> > >>> x==1 > >> [1] FALSE > >>> > >> > >> So, dput(x) gives 1, but x is not equal to 1. Can anyone advise? > >> > >> ______________________________________________ > >> R-devel at r-project.org mailing list > >> https://stat.ethz.ch/mailman/listinfo/r-devel > >> > > > > ______________________________________________ > > R-devel at r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >-- Steven Dirkse, Ph.D. GAMS Development Corp. office: 202.342.0180 [[alternative HTML version deleted]]