2012-03-06 4 views
1

У меня есть программа:C- с плавающей точкой точность

int main() 
{ 
     float f = 0.0f; 
     int i; 

     for (i = 0 ; i < 10 ; i++) 
       f = f + 0.1f; 

     if (f == 1.0f) 
       printf("f is 1.0 \n"); 
     else 
       printf("f is NOT 1.0\n"); 

     return 0; 
} 

Он всегда печатает f is NOT 1.0. Я понимаю, что это связано с точностью с плавающей точкой в ​​C. Но я не уверен, где именно он перепутался. Может кто-нибудь, пожалуйста, объясните мне, почему он не печатает другую строку?

+6

Вы сами ответили на вопрос. Это связано с точностью. Google даст вам 1000.001 объяснений. – John3136

ответ

2

Вы не можете сравнивать такие поплавки. Вы должны определить порог и сравнить на основе этого. This блоге объясняет

+0

Большое спасибо за ответ. Я прошел через ссылку и нашел другую ссылку, которая объяснила мне, чего я не вижу. http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm – Pkp

+0

@Прасанна, добро пожаловать! –

2

Для чисел с плавающей точкой вы всегда должны использовать значение эпсилон при их сравнении:

#define EPSILON 0.00001f 

inline int floatsEqual(float f1, float f2) 
{ 
    return fabs(f1 - f2) < EPSILON; // or fabsf 
} 
+2

Richard, +1, так как я предпочитаю автономные ответы, но функция, которую вы ищете, это 'fabs', а не' abs' - я исправил это для вас :-) – paxdiablo

+0

Спасибо. Это помогает и объясняет многое. – Pkp

+1

@prasanna не проблема, просто не забудьте принять ответ! –

4

двоичных данных с плавающей запятой не может представлять значение 0.1 точно, потому что его двоичное разложение не имеет конечное число цифр (точно так же, как десятичное разложение 1/7 не).

Двоичный расширение 0.1

0.000110011001100110011001100... 

При усекается до IEEE-754 с одинарной точностью, это примерно 0.100000001490116119 в десятичной системе. Это означает, что каждый раз, когда вы добавляете значение «почти 0,1» в свою переменную, вы накапливаете небольшую ошибку, поэтому конечное значение немного выше 1.0.

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