Thank you for this explanation! I have a long background in C/C++ and never realized this was such an issue with some languages. At least, with trivial single digit decimals. I understand accuracy issues with very large decimals, repeating or non-terminating rationals and I have handled them in the past. It makes me worried about all the R scripts I have written before (yikes!). Cheers -nb On Wed, 2 Feb 2022 at 02:44, Richard M. Heiberger <rmh at temple.edu> wrote:> RShowDoc('FAQ') > > then search for 7.31 > > > This statement > "If you stop at a 5 or 7 or 8 and back up to the previous digit, you round > up. Else you leave the previous result alone." > is not quite right. The recommendation in IEEE 754, and this is how R > does arithmetic, is to Round Even. > > I ilustrate here with decimal, even though R and other programs use binary. > > > x <- c(1.4, 1.5, 1.6, 2.4, 2.5, 2.6, 3.4, 3.5, 3.6, 4.4, 4.5, 4.6) > > r <- round(x) > > cbind(x, r) > x r > [1,] 1.4 1 > [2,] 1.5 2 > [3,] 1.6 2 > [4,] 2.4 2 > [5,] 2.5 2 > [6,] 2.6 3 > [7,] 3.4 3 > [8,] 3.5 4 > [9,] 3.6 4 > [10,] 4.4 4 > [11,] 4.5 4 > [12,] 4.6 5 > > > > Numbers whose last digit is not 5 (when in decimal) round to the nearest > integer. > Numbers who last digit is 5 (1.5, 2.5, 3.5, 4.5 above) > round to the nearest EVEN integer. > Hence 1.5 and 3.5 round up to the even numbers 2 and 4. > 2.5 and 4.5 round down do the even numbers 2 and 4. > > This way the round ups and downs average out to 0. If we always went up > from .5 we would have > an updrift over time. > > For even more detail click on the link in FAQ 7.31 to my appendix > https:// link.springer.com/content/pdf/bbm%3A978-1-4939-2122-5%2F1.pdf > and search for "Appendix G". > > Section G.5 explains Round to Even. > Sections G.6 onward illustrate specific examples, such as the one that > started this email thread. > > Rich[[alternative HTML version deleted]]
The base 2 representation of 0.4 repeats the digit sequence 1001 infinitely, hence must be rounded. The problem occurs in C the same as it does in R. bill at Bill-T490:~$ cat a.c #include <stdio.h> int main(int argc, char* argv[]) { double d = 0.4 + 0.3 + 0.2 + 0.1; printf("0.4+0.3+0.2+0.1 -> %24.17g\n", d); printf("0.4+0.3+0.2+0.1 == 1.0 -> %s\n", d == 1.0 ? "true" : "false"); return 0; } bill at Bill-T490:~$ gcc a.c bill at Bill-T490:~$ ./a.out 0.4+0.3+0.2+0.1 -> 0.99999999999999989 0.4+0.3+0.2+0.1 == 1.0 -> false -Bill On Tue, Feb 1, 2022 at 7:01 PM Nathan Boeger <nboeger at gmail.com> wrote:> Thank you for this explanation! > > I have a long background in C/C++ and never realized this was such an issue > with some languages. At least, with trivial single digit decimals. I > understand accuracy issues with very large decimals, repeating or > non-terminating rationals and I have handled them in the past. It makes me > worried about all the R scripts I have written before (yikes!). > > Cheers > > -nb > > On Wed, 2 Feb 2022 at 02:44, Richard M. Heiberger <rmh at temple.edu> wrote: > > > RShowDoc('FAQ') > > > > then search for 7.31 > > > > > > This statement > > "If you stop at a 5 or 7 or 8 and back up to the previous digit, you > round > > up. Else you leave the previous result alone." > > is not quite right. The recommendation in IEEE 754, and this is how R > > does arithmetic, is to Round Even. > > > > I ilustrate here with decimal, even though R and other programs use > binary. > > > > > x <- c(1.4, 1.5, 1.6, 2.4, 2.5, 2.6, 3.4, 3.5, 3.6, 4.4, 4.5, 4.6) > > > r <- round(x) > > > cbind(x, r) > > x r > > [1,] 1.4 1 > > [2,] 1.5 2 > > [3,] 1.6 2 > > [4,] 2.4 2 > > [5,] 2.5 2 > > [6,] 2.6 3 > > [7,] 3.4 3 > > [8,] 3.5 4 > > [9,] 3.6 4 > > [10,] 4.4 4 > > [11,] 4.5 4 > > [12,] 4.6 5 > > > > > > > Numbers whose last digit is not 5 (when in decimal) round to the nearest > > integer. > > Numbers who last digit is 5 (1.5, 2.5, 3.5, 4.5 above) > > round to the nearest EVEN integer. > > Hence 1.5 and 3.5 round up to the even numbers 2 and 4. > > 2.5 and 4.5 round down do the even numbers 2 and 4. > > > > This way the round ups and downs average out to 0. If we always went up > > from .5 we would have > > an updrift over time. > > > > For even more detail click on the link in FAQ 7.31 to my appendix > > https:// link.springer.com/content/pdf/bbm%3A978-1-4939-2122-5%2F1.pdf > > and search for "Appendix G". > > > > Section G.5 explains Round to Even. > > Sections G.6 onward illustrate specific examples, such as the one that > > started this email thread. > > > > Rich > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > 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. >[[alternative HTML version deleted]]
Please don't be dense. Not "some languages"... the discussion here has tried very hard to explain why this affects all of them. Including C/C++ (R is written in C). Look at [1] if you don't believe us. [1] https://0.30000000000000004.com/ On February 1, 2022 7:00:44 PM PST, Nathan Boeger <nboeger at gmail.com> wrote:>Thank you for this explanation! > >I have a long background in C/C++ and never realized this was such an issue >with some languages. At least, with trivial single digit decimals. I >understand accuracy issues with very large decimals, repeating or >non-terminating rationals and I have handled them in the past. It makes me >worried about all the R scripts I have written before (yikes!). > >Cheers > >-nb > >On Wed, 2 Feb 2022 at 02:44, Richard M. Heiberger <rmh at temple.edu> wrote: > >> RShowDoc('FAQ') >> >> then search for 7.31 >> >> >> This statement >> "If you stop at a 5 or 7 or 8 and back up to the previous digit, you round >> up. Else you leave the previous result alone." >> is not quite right. The recommendation in IEEE 754, and this is how R >> does arithmetic, is to Round Even. >> >> I ilustrate here with decimal, even though R and other programs use binary. >> >> > x <- c(1.4, 1.5, 1.6, 2.4, 2.5, 2.6, 3.4, 3.5, 3.6, 4.4, 4.5, 4.6) >> > r <- round(x) >> > cbind(x, r) >> x r >> [1,] 1.4 1 >> [2,] 1.5 2 >> [3,] 1.6 2 >> [4,] 2.4 2 >> [5,] 2.5 2 >> [6,] 2.6 3 >> [7,] 3.4 3 >> [8,] 3.5 4 >> [9,] 3.6 4 >> [10,] 4.4 4 >> [11,] 4.5 4 >> [12,] 4.6 5 >> > >> >> Numbers whose last digit is not 5 (when in decimal) round to the nearest >> integer. >> Numbers who last digit is 5 (1.5, 2.5, 3.5, 4.5 above) >> round to the nearest EVEN integer. >> Hence 1.5 and 3.5 round up to the even numbers 2 and 4. >> 2.5 and 4.5 round down do the even numbers 2 and 4. >> >> This way the round ups and downs average out to 0. If we always went up >> from .5 we would have >> an updrift over time. >> >> For even more detail click on the link in FAQ 7.31 to my appendix >> https:// link.springer.com/content/pdf/bbm%3A978-1-4939-2122-5%2F1.pdf >> and search for "Appendix G". >> >> Section G.5 explains Round to Even. >> Sections G.6 onward illustrate specific examples, such as the one that >> started this email thread. >> >> Rich > > [[alternative HTML version deleted]] > >______________________________________________ >R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >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.-- Sent from my phone. Please excuse my brevity.