Почему этот код на C генерирует double вместо float?

StackOverflow https://stackoverflow.com/questions/38198

  •  09-06-2019
  •  | 
  •  

Вопрос

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top