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 at 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 at Bill-T490:~$ gcc b.c
bill at 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 <nboeger at 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 <williamwdunlap at
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 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]]