Floats have 23 bits of precision so the rounding is done there instead of at 52 bits, hence a different example is needed to show the problem with floats.
bill@Bill-T490:~$ cat b.c #include <stdio.h> int main(int argc, char* argv[]) { float d = 0.4 + 0.4 + 0.4 + 0.4; printf("0.4+0.4+0.4+0.4 -> %24.17g\n", (double)d); printf("0.4+0.4+0.4+0.4 == 1.6 -> %s\n", d == 1.0 ? "true" : "false"); return 0; } bill@Bill-T490:~$ gcc b.c bill@Bill-T490:~$ ./a.out 0.4+0.4+0.4+0.4 -> 1.6000000238418579 0.4+0.4+0.4+0.4 == 1.6 -> false There is no getting around the fact that rounding will happen. -Bill On Tue, Feb 1, 2022 at 9:06 PM Nathan Boeger <nboe...@gmail.com> wrote: > > I understand this and with C the data type used is important. For this > type of calculation, I would normally use a float (basic single precision > is all I require). > > #include <stdio.h> > > void main() { > float foo = (0.4 + 0.2 + 0.30 + 0.1) ; > printf("foo: %f , foo > 1: %s \n", foo, (foo > 1.0 ? "true" : "false")); > double bar = (0.4 + 0.2 + 0.30 + 0.1) ; > printf("bar: %lf , bar > 1: %s \n", bar, (bar > 1.0 ? "true" : "false")); > } > > gcc c-check.c -o c-check > ./c-check > foo: 1.000000 , foo > 1: false > bar: 1.000000 , bar > 1: true > > Again, it was my mistake for not reading the R-FAQ. I had no idea it would > spark such a long thread. > > Cheers > > -nb > > On Wed, 2 Feb 2022 at 10:30, Bill Dunlap <williamwdun...@gmail.com> wrote: > >> 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@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@Bill-T490:~$ gcc a.c >> bill@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 <nboe...@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 <r...@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@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]] ______________________________________________ R-help@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.