Почему этот код на C генерирует double вместо float? - PullRequest
4 голосов
/ 01 сентября 2008

celsius = (5.0/9.0) * (fahr-32.0);

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

Ответы [ 5 ]

26 голосов
/ 01 сентября 2008
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: как отметил Вайбхав, типы повышаются таким образом, чтобы избежать Потеря точности.

4 голосов
/ 01 сентября 2008

Я думаю, что причина в том, чтобы обеспечить охват любого результата. поэтому естественный выбор является двойным, так как это самый большой тип данных.

3 голосов
/ 01 сентября 2008

Причина, по которой выражение приводится к двойной точности, заключается в том, что указанные литералы являются значениями двойной точности по умолчанию. Если вы укажете литералы, используемые в уравнении, как числа с плавающей точкой, выражение вернет число с плавающей точкой. Рассмотрим следующий код (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
1 голос
/ 20 августа 2009

Еще во времена K & Rv1 было рекомендовано использовать взаимозаменяемость с плавающей запятой / double, поскольку все выражения с типами с плавающей запятой всегда оценивались с использованием представления "double", что является проблемой в случаях, когда эффективность имеет первостепенное значение. Константа с плавающей точкой без суффиксов f, F, l или L имеет тип double. И, если буква f или F является суффиксом, константа имеет тип float. И если к нему добавляется буква l или L, он имеет тип long double.

1 голос
/ 01 сентября 2008

Константы с плавающей точкой должны иметь максимально возможную точность. Результат можно присвоить поплавку без лишних проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...