¿Cómo se hace la exponenciación en C?

4 minutos de lectura

Intenté “x = y ** e”, pero eso no funcionó.

  • Querías decir e**y en vez de y**e?

    usuario1142217

    25 de junio de 2018 a las 0:35


avatar de usuario
Evan Terán

utilizar el pow función (se necesita floats/doubleaunque).

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);

EDITAR: Para el caso especial de potencias enteras positivas de 2puede usar el cambio de bits: (1 << x) igualará 2 al poder x. Hay algunos problemas potenciales con esto, pero en general, sería correcto.

  • No estoy seguro de si esto sigue siendo cierto con las optimizaciones del compilador, pero el cambio de bits es una de las operaciones más rápidas en la CPU. Yo tomaría ese enfoque si es posible.

    – Blue Meanie

    24/06/2014 a las 18:40

  • no entiendo tu respuesta… podrías dar algún número enchufado en el ejemplo…

    – Martian2049

    9 oct 2018 a las 13:07

  • ¿Qué parte no entiendes? ¿Fue la parte de cambio de bits? Generalmente hablando, pow(2, x) == (1 << x) Entonces, pow(2, 4) == 16 y (1 << 4) == 16)

    – Evan Terán

    10 oct 2018 a las 20:33

  • Si desea una potencia integral de coma flotante rápida de 2, puede usar ldexpldexp(1.0, 100) te dará 2**100. También funciona para poderes negativos.

    – Chris Dodd

    5 oct 2021 a las 22:49


avatar de usuario
adam rosenfield

Para agregar a lo que dijo Evan: C no tiene un operador incorporado para la exponenciación, porque no es una operación primitiva para la mayoría de las CPU. Por lo tanto, se implementa como una función de biblioteca.

Además, para calcular la función e^x, puede usar el exp(double), expf(float)y expl(long double) funciones

Tenga en cuenta que lo hace no quiero usar el ^ operador, que es el O exclusivo bit a bit operador.

  • Solo estoy aprendiendo C, y eso ^ me lanzó a un gran bucle al principio. Estoy empezando a “entenderlo” ahora, pero su recordatorio es muy valioso para mí y (estoy seguro) para cientos más como yo. +1!

    – Juan Rudy

    17/10/2008 a las 18:40

  • @AlexejMagura: dado que 62 ^ 3 es una operación xor (0x3E ^ 0x03 en hexadecimal), el resultado es 0x3D (61), que no es lo mismo que el cubo de 62 (también conocido como 238328 o 0x03A2F8).

    –Jonathan Leffler

    5 abr 2018 a las 19:39

  • @AlexejMagura: OK, eso es curioso. ¿Deberíamos limpiar estos comentarios?

    –Jonathan Leffler

    11 de abril de 2018 a las 18:39

avatar de usuario
efímero

pow solo funciona en números de punto flotante (doubles, en realidad). Si desea tomar potencias de números enteros, y no se sabe que la base sea un exponente de 2tendrás que rodar el tuyo.

Por lo general, la forma tonta es lo suficientemente buena.

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

Aquí hay una solución recursiva que toma O(log n) espacio y tiempo en lugar de lo fácil O(1) espacio O(n) hora:

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;
    }
}

  • funcionará bien si lanzas tu int a un doble/flotante y luego vuelves a int.

    – Evan Terán

    17 de octubre de 2008 a las 18:55

  • Sin embargo, ineficiente y error de redondeo. voluntad marcar la diferencia cuando el resultado se acerque a INT_MAX.

    – efímero

    17/10/2008 a las 20:36

Similar a una respuesta anterior, esto manejará muy bien las potencias enteras positivas y negativas de un doble.

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;
}

avatar de usuario
jonathan leffler

La versión no recursiva de la función no es demasiado difícil; aquí está para números enteros:

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);
}

(Hackeado el código para elevar un valor doble a una potencia entera; tuvo que eliminar el código para tratar con los recíprocos, por ejemplo).

  • Sí, O(1) espacio O(log n) tiempo hace que esto sea mejor que la solución recursiva, pero un poco menos obvio.

    – efímero

    18 de octubre de 2008 a las 18:31

avatar de usuario
Ninguna

o simplemente podría escribir la función de potencia, con la recursividad como una ventaja adicional

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

sí, sí, sé que esto es menos eficiente en el espacio y la complejidad del tiempo, ¡pero la recursividad es más divertida!

  • Sí, O(1) espacio O(log n) tiempo hace que esto sea mejor que la solución recursiva, pero un poco menos obvio.

    – efímero

    18 de octubre de 2008 a las 18:31

avatar de usuario
Anónimo

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

(iterativo)

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

(si tiene que ser recursivo)

En mi opinión, el algoritmo definitivamente debería ser O (logn)

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad