2009-10-10 20 views
5

Cuando intento tomar la raíz N de un número pequeño con C#, obtengo un número incorrecto.La enésima raíz del número pequeño devuelve un resultado inesperado en C#

Por ejemplo, cuando intento tomar la tercera raíz de 1.07, obtengo 1, lo que claramente no es cierto.

Aquí está el código exacto que estoy usando para obtener la tercera raíz.

MessageBox.Show(Math.Pow(1.07,(1/3)).toString()); 

¿Cómo puedo resolver este problema?

Supongo que se trata de un problema aritmético de punto flotante, pero no sé cómo manejarlo.

+2

En realidad es un problema de la división entera. 1/3 se evalúa como enteros con el resultado de que la división es 0. Por lo tanto, realmente está tomando 1,07 hasta la 0ª potencia, que es 1. – tvanfosson

Respuesta

9

Estoy bastante seguro de que el "código exacto" que das no compila.

MessageBox.Show(Math.Pow(1.07,(1/3).toString())); 

La llamada a toString es en el nivel de anidamiento mal, es necesario que haya ToString, y (1/3) es la división entera, que es probablemente el verdadero problema que está teniendo. (1/3) es 0 y cualquier cosa para la potencia zeroth es 1. Necesita usar (1.0/3.0) o (1d/3d) o ...

+0

Estimado capitán sarcástico. Perdón por lo perdido). Debería haber copiado y pegado en lugar de volver a escribir. Ahora he corregido la información. ¡Gracias por la excelente respuesta! –

+0

p. funcionó muy bien –

+6

Normalmente no señalaría un error de sintaxis obvio, pero de alguna manera me sentí obligado porque se molestó en usar la palabra "exacto". Me alegro de que haya ayudado. –

13

C# es el tratamiento de los 1 y el 3 como enteros, es necesario hacer lo siguiente:

Math.Pow(1.07,(1d/3d)) 

o

Math.Pow(1.07,(1.0/3.0)) 

En realidad, es interesante porque la conversión de ampliación implícita hace que usted hace una Error.

3

Lo primero es lo primero: si ese es el código exacto que ' está utilizando, es probable que haya algo malo con su compilador :-)

MessageBox.Show(Math.Pow(1.07,(1/3).toString())); 

evaluará (1/3) .toString() primero y luego tratar de elevar 1,07 al poder de esa cadena.

pienso decir:

MessageBox.Show(Math.Pow(1.07,(1/3)).ToString()); 

En cuanto al problema, (1/3) está siendo tratado como una división entera de regresar 0 yn es 1 para todos los valores de n.

Necesita forzarlo a una división de coma flotante con algo como 1.0/3.0.

+0

Disculpa por el extravío). Debería haber copiado y pegado en lugar de volver a escribir. Ahora he corregido la información. –

1

Esto puede ayudar en caso de tener un problema real de precisión raíz enésima, pero mi experiancia es que el Math.pow orden interna (doble, int) es más preciso:

private static decimal NthRoot(decimal baseValue, int N) 
    { 
     if (N == 1) 
      return baseValue; 
     decimal deltaX; 
     decimal x = 1M; 
     do 
     { 
      deltaX = (baseValue/Pow(x, N - 1) - x)/N; 
      x = x + deltaX; 
     } while (Math.Abs(deltaX) > 0); 
     return x; 
    } 

    private static decimal Pow(decimal a, int b) 
    { 
     if (b == 0) return 1; 
     if (a == 0) return 0; 
     if (b == 1) return a; 
     if (b % 2 == 0) 
      return Pow(a * a, b/2); 
     else if (b % 2 == 1) 
      return a * Pow(a * a, b/2); 
     return 0; 
    } 
Cuestiones relacionadas