2010-10-23 24 views
15

Necesito calcular la potencia (10, n)¿Está bien utilizar Math.Pow (10, n)?

¿Está bien usar Math.Pow (10, n)?

¿O debería usar un bucle?

for (int i = 0; i < n; i++){ 
    x*=10; 
} 

¿Cuál es mejor? ¿y por qué?

+8

¿Por qué piensas que 'Math.Pow' es * no * ok? –

+0

¿Utilizarías un ciclo para agregar 10 n veces, o solo usarías 10 * n? :-) – CesarGon

+4

No sé .NET, pero el OP probablemente esté preocupado por el hecho de que Pow toma un flotador y devuelve un flotador, cuando podría hacerlo con solo enteros (si n no es demasiado grande). –

Respuesta

9

Si tanto la base como el exponente son enteros, podría considerar no usar Pow. Pero incluso en ese caso, Pow suele ser mejor porque es más legible. Si al menos uno es un valor de punto flotante, use Pow.

Si el exponente es 0.5 debe usar Sqrt, y si el exponente es un entero pequeño (2,3,4) expresar la fórmula con multiplicaciones es más rápido, pero menos legible.

Si desea implementar exponenciación rápida con un exponente entero, el algoritmo de cuadratura y multiplicación y no un bucle simple puede ser lo que desee. Pero en la mayoría de los escenarios, Pow es aún más rápido.

1

Math.Pow se proporciona para usted, y está bien documentado.

Cualquier gotchas se encuentran en la documentación.

¿Por qué usted no desea utilizar una función provista?

+0

Debido a errores de redondeo. ¿Quieres probar '10^4.99999999997'? – ja72

4

Depende de cuál comunique más claramente "10 a la potencia de n".

En mi caso, Math.Pow(10, n) (aunque podría significar matemáticas, colectivamente, punching 10 yn en sus caras también, no sé).

Es similar a cómo prefiero algebraicamente Express "10 a la potencia de n", como 10^n (o 10n) que 10 * 10 * 10 * ... * 10 n times, sobre todo teniendo en cuenta que n es variable.

-1

Sí, está bien usar Math.Pow().

8

Para enteros, tal vez un bucle for es más rápido que Math.Pow, que probablemente trata con números de coma flotante. Pero dudo mucho que la diferencia sea significativa en su caso (aunque yo no lo sé).

Pero si trabajas con enteros de 32 bits enteros, entonces solo puedes almacenar los valores de 10^n para n < = 9. Pero luego ganarías velocidad (y tal vez legibilidad) almacenando estos nueve (diez) poderes de diez en una matriz. Esto no es difícil: son (1), 10, 100, 1000, ...

Si necesita calcular 10^n para una n más grande, necesita usar números de coma flotante. Y entonces no hay ninguna razón para no usar Math.Pow. Esto es lo más rápido posible y fácil de leer.

+0

De todos modos: una computadora moderna puede hacer (decenas) de millones de exponenciaciones de puntos flotantes por segundo, así que a menos que esté haciendo algunos bucles realmente apretados en un juego 3D avanzado, el rendimiento no sería un problema ... –

+1

+ 1 para usar una búsqueda - seguramente más rápido si 'n <= 9' (como debe ser para que un' int' contenga el resultado) – AakashM

7

Math.Pow es mejor.
Aquí está regla general - en el 99% de los casos, favorezca las funciones integradas sobre las implementaciones personalizadas. Esto hace que su código sea más claro, le ahorra mucho trabajo y reduce las posibilidades de errores.

Solo cuando piense en usar funciones integradas de maneras que no estaban destinadas a ser utilizadas, o cuando tengan graves problemas de latencia (nunca he encontrado estos escenarios, para ser honesto), ¿debería considerar construir su implementación.

3

La respuesta sería normalmente sí, use Math.Pow().

Sin embargo, si este código es realmente crítico en el tiempo y usted sabe que se trata de pequeñas potencias 1-9 para que el resultado se pueda expresar en un Int32, entonces puede valer la pena optimizarlo. Acabo de hacer una aplicación de prueba rápida y perfilé las dos versiones (asegurándome de que el compilador no había optimizado ningún código) y el resultado en mi computadora portátil para el peor de los casos 10^9 fue que el ciclo fue 20 veces más rápido que Math.Pow (10,9).

Pero recuerde, quizás este cálculo no sea realmente un cuello de botella después de todo. Si sabe con certeza que lo es, p. si ha perfilado su aplicación y ha encontrado que es un problema real, continúe y reemplácela con un método basado en bucles (o incluso mejor, una búsqueda en matriz). Si solo está adivinando que puede ser un problema, le sugiero que se adhiera a Math.Pow. En general: solo optimice el código que sabe es un cuello de botella de rendimiento.

Cuestiones relacionadas