На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
[!] Как относитесь к модерированию на этом форуме? Выскажите свое мнение здесь
Модераторы: Qraizer
  
> На чистейшем СИ создать МАКРО возведение в степень , идеально чистый СИ (С89)
    Всем хай! Прямо сходу залетаем в дело!

    Есть ли возможность средствами языка чистейшего СИ (АНСИ стандарт / С89) создать макрос, имитирующий выполнение функции pow(основание; степень)??
    Скажу честно, что кроме
    ExpandedWrap disabled
      #define описание константы
    в си практически ничего не использую.

    насколько помню pow имеет кучу перегрузок. В идеале МАКРО должен тоже их поддерживать (с точки зрения функциональности), если это НЕВОЗМОЖНО, то хотя бы максимум функционала взять от pow.

    Подскажите как быть-то...

    ЗЫ: я хорошо понимаю, как соорудить МАКРО возводящий тупо в квадрат или куб, а вот чтоб произвольное в произвольную степень...хм...
    Сообщение отредактировано: FasterHarder -
      Очевидно, что возможность есть. Число=степень можно тупо макросом разложить на биты, а там уже сверхдлинным макросом собрать результат. ;)

      Для начала, расскажите как будете в степень 1/2 макросом возводить? :D
        FasterHarder, ты хочешь решить это макросом!
        Решением "в лоб" считаю нереальным. Я бы посмотрел в сторону приближенного вычисления, вот интересная тема. Тут скорее в математику нужно лезть с головой, чем программировать.
          Цитата FasterHarder @
          ... насколько помню pow имеет кучу перегрузок.
          Ну это в Плюсах перегрузки. В Cях разные функции.
          Перегрузки там не спроста. Они по-разному реализуют алгоритм, г.о. оптимизируя его под разные типы. Где нужна большая точность, там больше итераций, где не нужна, нечего лишние биты рассчитывать. Для целочисленного показателя трансцендентные операции вообще не используются. Если ты предполагаешь, что макросом сэкономишь накладные расходы посредством встраивания кода, боюсь разочаровать, избыточные или неэффективные операции сожрут весь профит от встраивания и добавят от себя приличный такой оверхед.


          Сообщение отредактировано: JoeUser -
            Цитата Qraizer @
            В Cях разные функции.

            кстати, залез ради интереса внутрь <math.h> и там даже через директивы мутят:
            ExpandedWrap disabled
              #define powl(x,y)       ((long double)pow((double)(x), (double)(y)))
              #define powf(x,y)   ((float)pow((double)(x), (double)(y)))


            т е в основе лежит вызов просто pow, а, используя приведения типов, выводят на нужную точность, ну, ок)

            в общем я понял, что макросом такое НЕ сделать даже физически, ну, ок)

            Qraizer, кстати в заголовочном файле <math.h> встретился такой код:
            ExpandedWrap disabled
              extern "C++" {
               
              template<class _Ty> inline
                      _Ty _Pow_int(_Ty _X, int _Y)
              ....


            так это чего получается, что некоторые фрагменты "библиотеки" СИ написаны на С++?? это норм.? или я совсем чего-то не понимаю)
              Если я тебе скажу, что библиотеки C в Visual Studio 2017, а может и более ранних, целиком написаны на C++, ты поверишь? Вообще же, конкретно тут – скорее всего нет. extern "C++" означает связывание языка C++, которое Стандартом языка C не определяется. Даже такой формат extern, с указанием типа связывания, в C отсутствует. (Впрочем, не исключено, что я отстал от жизни, и в новых ратификациях оно уже есть.) Хотя возможно, что это расширение Стандарта языка в некой конкретной реализации. Каком-нибудь там порте GCC.
              Но в C++ такой формат есть изначально, и там определены два типа связывания: "C" и "C++". Конкретные реализации могут предлагать и другие, например "Pascal", "Fortran" итп. Тип связывания указывает компилятору, на каком языке написана эта функция, а значит соглашения этого языка об именованиях функций, способов их вызова и передачи параметров должны известны компилятору, и он должен применять к ней их. Тоже может быть применено и к переменным. Формально тип связывания должен быть указан для каждого имени функции и переменной, но в Стандарте C++ сказано, что если явно ничего не задано, должно применяться "C++". Так что если бы вон та первая строка отсутствовала, смысл был бы тем же самым. В режиме компиляции C++, конечно.
              Если код рассчитан на оба языка, то естественно в режиме компиляции C без этой строки применялись бы правила "C". Если код уже откомпилирован и лежит в объектном файле, то это может повлечь невозможность сборки приложения, т.к. линкер просто не найдёт нужных имён. Обычно в подобных случаях это обходят условной компиляцией, только делают наоборот:
              ExpandedWrap disabled
                #ifdef __cplusplus
                 
                /* тут код C++ */
                extern "C"
                {
                 
                #else
                 
                /* тут код C */
                typedef _Bool bool;
                 
                #endif
                 
                /* тут общий код */
                bool func(int);
                 
                #ifdef __cplusplus
                }
                #endif
              Макрос __cplusplus определён в Стандарте C++ и отсутствует в Стандарте C. Так что в любом режиме компиляции этот код снабдит компиляторы правильной инфой.

              Добавлено
              Цитата FasterHarder @
              кстати, залез ради интереса внутрь <math.h> и там даже через директивы мутят:
              ...
              Конкретно тут реализация одна, а остальные сводятся к ней. Вероятно нет никакой выгоды от сокращения точности вычислений, тип машинных данных всегда один и тот же, как например на FPU какого-нибудь x86, где все вычисления выполняются в 80-битном формате. Другое дело, если за дело возьмётся оптимизатор под SSE. Там для 32-х и 64-битных вещественных разница-таки есть и немалая. Ну и платформ с отличной от свойств x86 архитектурой хватает, всякие ARMы, например.

              Добавлено
              Цитата FasterHarder @
              в заголовочном файле <math.h> встретился такой код:
              За C не помню, что там с разными Стандартами, но в C++ перегрузка для целочисленной степени всегда была. Подразумевается, что реализация этой функции не будет использовать неточные и непроизводительные трансцендентные команды или численные методы, а реализует эффективный итерационный алгоритм возведения в квадрат с накоплением поправочных сомножителей.

              Добавлено
              Цитата FasterHarder @
              в общем я понял, что макросом такое НЕ сделать даже физически
              Ну почему же. Любой фрагмент кода, не пересекающего границы блока, можно завернуть в макрос. Вопрос в целесообразности. Ты ж не ответил, какого эффекта хочешь добиться. Чем тебе не такое, например:
              ExpandedWrap disabled
                #define POW(x, y) (exp((y)*log(x)))
              но что-то мне подсказывает, это не то, о чём бы ты стал не спрашивать.
                Qraizerну, спс. за такой ответ) круто! даже слишком круто!)

                Цитата Qraizer @
                Чем тебе не такое, например

                скорее всего, именно это и есть лучший вариант реализации
                  Цитата FasterHarder @
                  скорее всего, именно это и есть лучший вариант реализации
                  Вот только он бессмысленный. Ты вряд ли что-то выиграешь, а в общем случае можешь и проиграть.
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0309 ]   [ 16 queries used ]   [ Generated: 19.04.24, 23:07 GMT ]