2017-01-24 3 views
1

Я получаю неожиданное поведение при сравнении значения с плавающей запятой, я понимаю, что поплавки могут иметь проблемы с округлением, но здесь цифры весьма специфичны, чтобы представить эти проблемы.C-кодирование, непредвиденное поведение при сравнении значения с плавающей запятой

#include <stdio.h> 
int main() 
{ 
    float alpha = 0.0f; 
    int finish = 0; 

    while (finish == 0) 
    { 
     alpha += 0.05f; 

     if (alpha > 1.0f) 
     { 
      printf("%f", alpha); // Expected result: 1.05f, actual result: 1.0f 
      finish = 1; 
     } 
    } 

    return 0; 
} 

Фактически, условие входит, когда α = 1.0f. Не могу понять это поведение ...

Я компилирую с MinGW (GCC 5.3.0) на Windows 10 (протестирован на 32-битных и 64-битных) процессорах Intel i5.

+3

Если вы хотите напечатать 'alpha' с более значимыми цифрами (например,' printf ("%. 7f \ n", alpha); '), вы сразу увидите проблему: http://ideone.com/zwQW7e , –

+1

Вы должны знать, является ли константа для 0.05f немного меньшей или немного больше, чем бесконечный поток битов, который будет точно представлять 0,05. Предположительно, он немного больше. –

+0

Проверьте это (это то, что я использовал для построения моего ответа): http: //www.exploringbinary.com/floating-point-converter/ – Bathsheba

ответ

2

(Ограничение ответа, если возможно, с плавающей точкой IEEE754).

Нет таких float, что и 0.05. ближайшего число представимо в том, что это

0.0500000007450580596923828125

Так что же происходит, является то, что немного большие значения, чем то, что вы думаете, будут добавлены в alpha, что достаточно для только толчок его над 1.0f знак (который, из интереса, могут быть представлены точно.)

форматирование по умолчанию в print округления, что немного больше, чем 1.0f номер назад 1.0f.

Таким образом, все это связано с бинарной плавающей точкой, не имеющей, в общем, точного десятичного представления.

+0

Я не согласен, хотя OP рекомендуется изучить дубликат. Даже вооруженный знаниями с плавающей точкой, приятно иметь объяснение для этого конкретного случая. (Для чего это стоит, я, вероятно, закрываю 2 или 3 вопроса с плавающей запятой, дублируясь с тем, который вы указали в неделю.) – Bathsheba

Смежные вопросы