Подтвердить что ты не робот

Почему кастинг для int не заполняет все дубликаты в C

С учетом кода C:

#include <math.h>  
#include <stdio.h>  
int main(){  
 int i;  
 double f=log(2.0)/log(pow(2.0,1.0/2.0));  
 printf("double=%f\n",f);  
 printf("int=%d\n",(int) f);  
}

Я получаю вывод:

double=2.000000
int=1

f, по-видимому, не менее 2,0. Почему значение отливки не равно 2?

4b9b3361

Ответ 1

Поскольку значение double было меньше 2

double=1.99999999999999978
int=1

Попробуйте, но на этот раз добавьте некоторую точность

#include <math.h>  
#include <stdio.h>  
int main(){  
 int i;  
 double f=log(2.0)/log(pow(2.0,1.0/2.0));  
 printf("double=%0.17f\n",f);  
 printf("int=%d\n",(int) f);  
}

Сбивать с толку, как первый раз, когда вы это испытываете. Теперь, если вы попробуете этот

#include <math.h>  
#include <stdio.h>  
int main(){  
 int i;  
 double f=log(2.0)/log(pow(2.0,1.0/2.0));  
 printf("double=%0.17f\n",f);  
 printf("int=%d\n",(int) f);  
 printf("int=%d\n", (int)round(f));
}

Он будет правильно округлять значение. Если вы посмотрите на странице руководства (по крайней мере, на mac), вы увидите следующий комментарий...

round, lround, llround -- round to integral value, regardless of rounding direction

Что они означают по направлению, все это указано в IEEE 754. Если вы проверите различные способы округления до целого числа..., то слово указано как округление по направлению к -ve infinity, которое в этом случае было в направлении 1:)

Ответ 2

Целое число не принимает округленное значение, но делает усечение. Итак, если f равно 1.999999999999 [..] 9, значение int будет равно 1.

Кроме того, поскольку двойник хочет быть более точным, он возьмет округленное значение, учитывая количество символов, которое он может показать, что равно 2.000000.

Ответ 3

Типы с плавающей точкой не могут точно представлять некоторые числа. Хотя математически вычисление должно быть ровно 2 с плавающими точками IEEE754, результат оказывается немного меньше 2. Для получения дополнительной информации см. этот вопрос.

Если вы увеличиваете точность вашего вывода, указав %.20f вместо просто %f, вы увидите, что число не равно 2, а при печати с меньшей точностью результат просто округлен.

При преобразовании в int, однако, используется полная точность типа с плавающей точкой, а так как оно достигает менее 2, результат при преобразовании в целое число равен 1.