Поплавковый расчет времени компиляции не происходит? - PullRequest
1 голос
/ 07 июня 2010

Маленькая тестовая программа:

#include <iostream>


const float TEST_FLOAT = 1/60;

const float TEST_A = 1;
const float TEST_B = 60;
const float TEST_C = TEST_A / TEST_B;

int main()
{
 std::cout << TEST_FLOAT << std::endl;
 std::cout << TEST_C << std::endl;

 std::cin.ignore();
 return 0;
}

Результат:

0
0.0166667

Протестировано в Visual Studio 2008 и 2010.

  1. Я работал над другими компиляторами, которые, если я хорошо помню, дали первый результат как второй результат. Теперь моя память может быть неправильной, но не должно ли TEST_FLOAT иметь то же значение, что и TEST_C? Если нет, то почему?
  2. Разрешается ли значение TEST_C во время компиляции или во время выполнения? Я всегда предполагал первое, но теперь, когда я вижу эти результаты, у меня есть некоторые сомнения ...

1 Ответ

11 голосов
/ 07 июня 2010

В

1/60

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

1.0/60
1.0/60.0
1/60.0

(вместо этого вы можете выбрать 1.0f, чтобы избежать предупреждений о снижении точности; 1.0 имеет тип double, а 1.0f имеет тип float)

Не должно ли TEST_FLOAT иметь то же значение, что и TEST_C?

В случае TEST_FLOAT выполняется целочисленное деление, а затем результат целочисленного деления преобразуется в float в присваивании.

В случае TEST_C целочисленные литералы 1 и 60 преобразуются в float, когда им назначаются TEST_A и TEST_B; затем выполняется деление с плавающей точкой на эти числа и результат присваивается TEST_C.

Разрешено ли значение TEST_C во время компиляции или во время выполнения?

Это зависит от компилятора; любой метод соответствовал бы стандартам.

...