Dlaczego dodawanie 0 do końca literału float zmienia sposób jego zaokrąglania (możliwy błąd GCC)?
Odkryłem na moim x86 VM (32-bitowym) następujący program:
#include <stdio.h>
void foo (long double x) {
int y = x;
printf("(int)%Lf = %d\n", x, y);
}
int main () {
foo(.9999999999999999999728949456878623891498136799780L);
foo(.999999999999999999972894945687862389149813679978L);
return 0;
}
Tworzy następujące dane wyjściowe:
(int)1.000000 = 1
(int)1.000000 = 0
Ideone wytwarza również takie zachowanie.
Co robi kompilator, aby tak się stało?
Znalazłem tę stałą, ponieważ śledziłem, dlaczego nie powstał następujący program0
jak się spodziewałem (używając 199
s wyprodukował0
Oczekiwałem):
int main () {
long double x = .99999999999999999999L; /* 20 9's */
int y = x;
printf("%d\n", y);
return 0;
}
Gdy próbowałem obliczyć wartość, przy której wynik przełącza się z oczekiwanego na nieoczekiwany, dotarłem do stałej odpowiedzi na to pytanie.