Как вы делаете возведение в степень в C?

Я попробовал «x = y ** e», но это не сработало.

Вы имели в виду e**y, а не y**e?

Ben Crowell 25.06.2018 03:35
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
58
1
245 457
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

используйте функцию pow (хотя она требует floats / doubles).

man pow:

   #include <math.h>

   double pow(double x, double y);
   float powf(float x, float y);
   long double powl(long double x, long double y);

РЕДАКТИРОВАТЬ: Для особого случая положительных целочисленных степеней 2 вы можете использовать битовый сдвиг: (1 << x) будет равняться 2 степени x. С этим есть некоторые потенциальные подводные камни, но в целом это было бы правильно.

Я не уверен, так ли это с оптимизацией компилятора, но битовый сдвиг - одна из самых быстрых операций на ЦП. Если возможно, я бы выбрал такой подход.

BlueMeanie 24.06.2014 22:40

я не понимаю вашего ответа ... не могли бы вы привести какой-нибудь номер в примере ...

Martian2049 09.10.2018 16:07

Какую часть вы не понимаете? Была ли это часть, меняющая бит? Вообще говоря, pow(2, x) == (1 << x) Итак, pow(2, 4) == 16 и (1 << 4) == 16)

Evan Teran 10.10.2018 23:33

Чтобы добавить к тому, что сказал Эван: C не имеет встроенного оператора для возведения в степень, потому что это не примитивная операция для большинства процессоров. Таким образом, он реализован как библиотечная функция.

Также для вычисления функции e ^ x можно использовать функции exp(double), expf(float) и expl(long double).

Обратите внимание, что вы делаете нет, хотите использовать оператор ^, который является оператором побитовое исключающее ИЛИ.

Я только изучаю C, и это поначалу бросило меня в большой цикл. Я начинаю «понимать» сейчас, но ваше напоминание очень ценно для меня и (я уверен) сотни таких же, как я. +1!

John Rudy 17.10.2008 22:40

@AlexejMagura: Поскольку 62 ^ 3 является операцией xor (0x3E ^ 0x03 в шестнадцатеричном формате), результатом будет 0x3D (61), что не то же самое, что куб 62 (он же 238328 или 0x03A2F8).

Jonathan Leffler 05.04.2018 22:39

@AlexejMagura: Хорошо, это любопытно. Следует ли нам убрать эти комментарии?

Jonathan Leffler 11.04.2018 21:39

или вы можете просто написать степенную функцию с рекурсией в качестве дополнительного бонуса

int power(int x, int y){
      if (y == 0)
        return 1;
     return (x * power(x,y-1) );
    }

да, да, я знаю, что это менее эффективная пространственно-временная сложность, но рекурсия просто веселее !!

pow работает только с числами с плавающей запятой (на самом деле double). Если вы хотите использовать степени целых чисел, а основание не является показателем 2, вам придется использовать собственный.

Обычно достаточно глупого пути.

int power(int base, unsigned int exp) {
    int i, result = 1;
    for (i = 0; i < exp; i++)
        result *= base;
    return result;
 }

Вот рекурсивное решение, которое использует пространство и время O(log n) вместо простого пространства O(1) времени O(n):

int power(int base, int exp) {
    if (exp == 0)
        return 1;
    else if (exp % 2)
        return base * power(base, exp - 1);
    else {
        int temp = power(base, exp / 2);
        return temp * temp;
    }
}

он будет работать нормально, если вы введете int в double / float, а затем вернетесь к int.

Evan Teran 17.10.2008 22:55

Однако неэффективность и ошибка округления воля имеют значение, когда результат приближается к INT_MAX.

ephemient 18.10.2008 00:36

Нерекурсивная версия функции не так уж и сложна - вот она для целых чисел:

long powi(long x, unsigned n)
{
    long p = x;
    long r = 1;

    while (n > 0)
    {
        if (n % 2 == 1)
            r *= p;
        p *= p;
        n /= 2;
    }

    return(r);
}

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

Да, O (1) space O (log n) time делает это лучше, чем рекурсивное решение, но немного менее очевидным.

ephemient 18.10.2008 22:31
int power(int x,int y){
 int r=1;
 do{
  r*=r;
  if (y%2)
   r*=x;
 }while(y>>=1);
 return r;
};

(итеративно)

int power(int x,int y){
 return y?(y%2?x:1)*power(x*x,y>>1):1;
};

(если он должен быть рекурсивным)

imo, алгоритм определенно должен быть O (logn)

Как и в предыдущем ответе, это будет хорошо обрабатывать положительные и отрицательные целые степени двойника.

double intpow(double a, int b)
{
  double r = 1.0;
  if (b < 0)
  {
    a = 1.0 / a;
    b = -b;
  }
  while (b)
  {
    if (b & 1)
      r *= a;
    a *= a;
    b >>= 1;
  }
  return r;
}

Другие вопросы по теме