Почему этот код на C генерирует double вместо float?
Вопрос
celsius = (5.0 / 9.0) * (fahr-32.0);
Это просто выбор разработчика, который решили разработчики C, или есть причина для этого? Я полагаю, что число с плавающей запятой меньше двойного, поэтому может быть предотвращено переполнение, вызванное незнанием того, какой десятичный формат использовать. Это причина или я что-то упускаю?
Решение
Я думаю, что причина в том, чтобы любой результат можно было охватить. поэтому естественный выбор является двойным, так как это самый большой тип данных.
Другие советы
celsius = (5.0/9.0) * (fahr-32.0);
В этом выражении 5.0
, 9.0
и 32.0
являются double
. Это тип по умолчанию для константы с плавающей точкой - если вы хотите, чтобы они были float
, то вы должны использовать суффикс F
:
celsius = (5.0F/9.0F) * (fahr-32.0F);
Обратите внимание, что если fahr
было double
, то результатом этого последнего выражения будет все же быть double
: как отметил Вайбхав, типы продвигаются таким образом, чтобы избежать потери точности.
Причина, по которой выражение приводится к двойной точности, заключается в том, что указанные литералы являются значениями двойной точности по умолчанию. Если вы укажете литералы, используемые в уравнении, как числа с плавающей точкой, выражение вернет число с плавающей точкой Рассмотрим следующий код (Mac OS X с использованием gcc 4.01). Р>
#include <stdio.h>
int main() {
float celsius;
float fahr = 212;
printf("sizeof(celsius) ---------------------> %d\n", sizeof(celsius));
printf("sizeof(fahr) ------------------------> %d\n", sizeof(fahr));
printf("sizeof(double) ----------------------> %d\n", sizeof(double));
celsius = (5.0f/9.0f) * (fahr-32.0f);
printf("sizeof((5.0f/9.0f) * (fahr-32.0f)) --> %d\n", sizeof((5.0f/9.0f) * (fahr-32.0f)));
printf("sizeof((5.0/9.0) * (fahr-32.0)) -----> %d\n", sizeof((5.0/9.0) * (fahr-32.0)));
printf("celsius -----------------------------> %f\n", celsius);
}
Вывод:
sizeof(celsius) ---------------------> 4
sizeof(fahr) ------------------------> 4
sizeof(double) ----------------------> 8
sizeof((5.0f/9.0f) * (fahr-32.0f)) --> 4
sizeof((5.0/9.0) * (fahr-32.0)) -----> 8
celsius -----------------------------> 100.000008
Константы с плавающей точкой должны иметь максимально возможную точность. Результат можно присвоить поплавку без лишних проблем.
Еще во времена K & amp; Rv1 было рекомендовано использовать взаимозаменяемость с плавающей запятой / double, поскольку все выражения с типами с плавающей запятой всегда оценивались с использованием представления "double", что является проблемой в случаях, когда эффективность имеет первостепенное значение. Константа с плавающей точкой без суффиксов f, F, l или L имеет тип double. И, если буква f или F является суффиксом, константа имеет тип float. И если к нему добавляется буква l или L, он имеет тип long double.