Я могу вычислить голову (10, x) во время компиляции в c?

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

11
задан AShelly 30 June 2009 в 21:53
поделиться

6 ответов

Существует очень мало возможных значений, прежде чем вы переполните int (или даже long). Для ясности сделайте это таблицей!

edit: Если вы используете числа с плавающей запятой (похоже, что вы это делаете), то нет '

21
ответ дан 3 December 2019 в 00:42
поделиться

GCC сделает это на достаточно высоком уровне оптимизации (-O1 сделает это за меня). Например:

#include <math.h>

int test() {
        double x = pow(10, 4);
        return (int)x;
}

Компилируется с -O1 -m32 в:

        .file   "test.c"
        .text
.globl test
        .type   test, @function
test:
        pushl   %ebp
        movl    %esp, %ebp
        movl    $10000, %eax
        popl    %ebp
        ret
        .size   test, .-test
        .ident  "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
        .section        .note.GNU-stack,"",@progbits

Это также работает без преобразования типов - конечно, вы получаете там инструкцию загрузки с плавающей запятой, как Linux ABI передает возвращаемые значения с плавающей запятой в регистры FPU.

19
ответ дан 3 December 2019 в 00:42
поделиться

Вы можете сделать это с помощью Boost.Preprocessor:

http://www.boost.org/doc/libs/1_39_0/libs/preprocessor/doc/index.html

Код:

#include <boost/preprocessor/repeat.hpp>

#define _TIMES_10(z, n, data) * 10
#define POW_10(n) (1 BOOST_PP_REPEAT(n, _TIMES_10, _))

int test[4] = {POW_10(0), POW_10(1), POW_10(2), POW_10(3)};
10
ответ дан 3 December 2019 в 00:42
поделиться

В последних версиях GCC (около 4.3) добавлена ​​возможность использования GMP и MPFR для выполнения некоторых оптимизаций во время компиляции путем оценки более сложных постоянных функций. Такой подход делает ваш код простым и переносимым, а всю тяжелую работу берет на себя компилятор.

Конечно, есть ограничения на то, что он может делать. Вот ссылка на описание в журнале изменений , которое включает список поддерживаемых им функций. «pow» - одно из них.

3
ответ дан 3 December 2019 в 00:42
поделиться

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

0
ответ дан 3 December 2019 в 00:42
поделиться

Воспроизведение bdonlan правильное, но имейте в виду, что вы можете выполнить практически любую оптимизацию, которую вы выбрали в блоке компиляции, при условии, что вы готовы разбирать и анализировать код в своем собственном препроцессоре. В большинстве версий unix это тривиальная задача - переопределить неявные правила, которые вызывают компилятор для вызова вашего собственного шага до того, как он попадет в компилятор.

0
ответ дан 3 December 2019 в 00:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: