writeline texto setcursorposition posicionar posicionamiento para ejemplos consola como comandos c# math integer exponentiation

texto - ¿Cómo se hace exponenciación*entero*en C#?



posicionamiento en consola c# (10)

¿Utiliza la versión doble, verifica el desbordamiento (sobre max int o max long) y envía a int o long?

La función Math.Pow() incorporada en .NET aumenta una double base a un double exponente y devuelve un double resultado.

¿Cuál es la mejor manera de hacer lo mismo con los enteros?

Agregado: Parece que uno puede simplemente arrojar el resultado de Math.Pow() a (int), pero ¿esto siempre producirá el número correcto y no habrá errores de redondeo?


Aquí hay una publicación de blog que explica la forma más rápida de elevar enteros a los poderes enteros. Como señala uno de los comentarios, algunos de estos trucos están integrados en chips.


Dos más...

public static int FastPower(int x, int pow) { switch (pow) { case 0: return 1; case 1: return x; case 2: return x * x; case 3: return x * x * x; case 4: return x * x * x * x; case 5: return x * x * x * x * x; case 6: return x * x * x * x * x * x; case 7: return x * x * x * x * x * x * x; case 8: return x * x * x * x * x * x * x * x; case 9: return x * x * x * x * x * x * x * x * x; case 10: return x * x * x * x * x * x * x * x * x * x; case 11: return x * x * x * x * x * x * x * x * x * x * x; // up to 32 can be added default: // Vilx''s solution is used for default int ret = 1; while (pow != 0) { if ((pow & 1) == 1) ret *= x; x *= x; pow >>= 1; } return ret; } } public static int SimplePower(int x, int pow) { return (int)Math.Pow(x, pow); }

Hice algunas pruebas de rendimiento rápido

  • mini-me: 32 ms

  • Sunsetquest (rápido): 37 ms

  • Vilx: 46 ms

  • Charles Bretana (también conocido como Cook): 166 ms

  • Sunsetquest (simple): 469 ms

  • 3dGrabber (versión de Linq): 868 ms

(Notas de prueba: Intel i7 2nd gen, .net 4, release build, release run, 1M bases diferentes, exp de 0-10 solamente)

Conclusión: mini-me''s es lo mejor en rendimiento y simplicidad

se realizó una prueba de precisión muy mínima


Eché el resultado a int, así:

double exp = 3.0; int result = (int)Math.Pow(2.0, exp);

En este caso, no hay errores de redondeo porque la base y el exponente son enteros. El resultado será un número entero también.


LINQ alguien?

public static int Pow(this int bas, int exp) { return Enumerable .Repeat(bas, exp) .Aggregate(1, (a, b) => a * b); }

uso como extensión:

var threeToThePowerOfNine = 3.Pow(9);


Mi solución favorita para este problema es una clásica solución recursiva para dividir y conquistar. En realidad es más rápido que multiplicar n veces, ya que reduce el número de multiplicaciones a la mitad cada vez.

public static int Power(int x, int n) { // Basis if (n == 0) return 1; else if (n == 1) return x; // Induction else if (n % 2 == 1) return x * Power(x*x, n/2); return Power(x*x, n/2); }

Nota: esto no verifica el desbordamiento o negativo n.


Para un corto y rápido delineador.

int pow(int i, int exp) => (exp == 0) ? 1 : i * pow(i, exp-1);

No hay exponente negativo ni controles de desbordamiento.


Una muy rápida podría ser algo como esto:

int IntPow(int x, uint pow) { int ret = 1; while ( pow != 0 ) { if ( (pow & 1) == 1 ) ret *= x; x *= x; pow >>= 1; } return ret; }

Tenga en cuenta que esto no permite potencias negativas. Lo dejo como un ejercicio para ti. :)

Agregó: Oh sí, casi lo olvidaste, también agregas la verificación de desbordamiento / desbordamiento, o puede que tengas algunas sorpresas desagradables en el futuro.


Usando las matemáticas en el enlace del blog de John Cook,

public static long IntPower(int x, short power) { if (power == 0) return 1; if (power == 1) return x; // ---------------------- int n = 15; while ((power <<= 1) >= 0) n--; long tmp = x; while (--n > 0) tmp = tmp * tmp * (((power <<= 1) < 0)? x : 1); return tmp; }

para abordar la objeción de que el código no funcionará si cambias el tipo de energía, bueno ... dejando de lado el punto de que cualquiera que cambie el código no lo entienda y luego lo use sin probar ...
pero para abordar el problema, esta versión protege al tonto de ese error ... (Pero no de una miríada de otros que podrían hacer) NOTA: no probado.

public static long IntPower(int x, short power) { if (power == 0) return 1; if (power == 1) return x; // ---------------------- int n = power.GetType() == typeof(short)? 15: power.GetType() == typeof(int)? 31: power.GetType() == typeof(long)? 63: 0; long tmp = x; while (--n > 0) tmp = tmp * tmp * (((power <<= 1) < 0)? x : 1); return tmp; }

Pruebe también este equivalente recursivo (más lento por supuesto):

public static long IntPower(long x, int power) { return (power == 0) ? x : ((power & 0x1) == 0 ? x : 1) * IntPower(x, power >> 1); }


lolz, ¿qué tal?

public static long IntPow(long a, long b) { long result = 1; for (long i = 0; i < b; i++) result *= a; return result; }