Арифметика с плавающей точкой во время компиляции - PullRequest
2 голосов
/ 11 декабря 2010

Выполняются ли вычисления с плавающей запятой, использующие целые числа времени компиляции, во время компиляции или во время выполнения? Например, когда вычисляется операция деления в:

template <int A, int B>
inline float fraction()
{
    return static_cast<float>(A) / B;
}

Ответы [ 5 ]

2 голосов
/ 11 декабря 2010

Для чего-то такого простого, компилятор , вероятно, сделает это во время компиляции.Фактически, компилятор, вероятно, сделает это во время компиляции, даже без шаблонов, при условии, что все значения известны во время компиляции: то есть, если у нас есть inline float fraction(int A, int B), он, вероятно, выполнит деление при компиляциивремя, если мы вызовем fraction(1,2).

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

// Something similarly simple that doesn't use floating-point ;)
template <int A, int B>
struct Product {
    enum { value = A * B };
};

// Later:
... Product<3, 4>::value ...
1 голос
/ 11 декабря 2010

Ни в стандартах C, ни в C ++ не требуется , чтобы константные выражения любой полосы оценивались во время компиляции, но они допускают это. Большинство компиляторов, выпущенных за последние 20 лет, будут оценивать арифметические выражения, поэтому, если важно не вызывать вызов функции или вставлять код, сохраняйте его как можно более простым.

Если область действия этих выражений ограничена одним файлом, вы всегда можете воспользоваться препроцессором и #define FRACTION(a,b) (float(a)/float(b)) для удобства. Я не рекомендую делать это в заголовке, если у вас нет хорошей схемы предотвращения загрязнения любого файла, который #include s.

1 голос
/ 11 декабря 2010

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

template <int A, int B>
inline float fraction()
{
    static const float f = static_cast<float>(A) / B;
    return f ;
}

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

1 голос
/ 11 декабря 2010

Вам следует дождаться gcc 4.6 с реализацией ключевого слова C ++ 0x constexpr .

1 голос
/ 11 декабря 2010

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

(Некоторые компиляторы могут этого не делать, потому что для некоторых архитектур поведение с плавающей запятой настраивается во время выполнения. Результаты для операции, выполняемой во время компиляции, могут потенциально отличаться от результатов той же операции, выполняемой во время выполнения.)

...