2009-10-10 2 views
5

Lorsque j'essaie de prendre la N e racine d'un petit nombre en utilisant C#, je reçois un mauvais numéro. Par exemple, lorsque j'essaie de prendre la troisième racine de 1.07, j'obtiens 1, ce qui n'est clairement pas vrai.Nième racine de petit nombre renvoie un résultat inattendu dans C#

Voici le code exact que j'utilise pour obtenir la troisième racine.

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

Comment résoudre ce problème?

Je suppose que c'est un problème d'arithmétique en virgule flottante, mais je ne sais pas comment le gérer.

+2

Il est en fait un problème de division entière. 1/3 est évalué comme un nombre entier avec le résultat de la division étant 0. Ainsi vous prenez vraiment 1,07 à la puissance 0 qui est 1. – tvanfosson

Répondre

9

Je suis assez sûr que le "code exact" que vous donnez ne compile pas.

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

L'appel à toString est au mauvais niveau d'imbrication, doit être ToString, et (1/3) est la division entière, ce qui est probablement le vrai problème que vous rencontrez. (1/3) est 0 et n'importe quoi à la puissance de zéro est 1. Vous devez utiliser (1.0/3.0) ou (1d/3d) ou ...

+0

Cher capitaine sarcastique. Désolé pour l'égaré). J'aurais dû copier et coller au lieu de retaper. J'ai maintenant corrigé l'info. Merci pour l'excellente réponse! –

+0

ps. fonctionnait bien –

+6

Normalement, je ne signalerais pas une erreur de syntaxe évidente, mais je me suis senti obligé d'utiliser le mot «exact». Content que cela ait aidé. –

13

C# est utilisé pour traiter les 1 et les 3 sous forme d'entiers, vous devez effectuer les opérations suivantes:

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

ou

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

Il est en fait intéressant, car la conversion d'élargissement implicite qui vous fait faire un erreur.

3

Les choses d'abord: si c'est le code exact que vous ' re à l'aide, il y a probablement quelque chose de mal avec votre compilateur :-)

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

évaluera (1/3) .toString() d'abord puis essayer et augmenter 1,07 à la puissance de cette chaîne.

Je pense que vous dire:

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

En ce qui concerne le problème, (1/3) est traité comme une division entière de retour 0 et n 0 est 1 pour toutes les valeurs de n.

Vous devez le forcer à une division en virgule flottante avec quelque chose comme 1.0/3.0.

+0

Désolé pour l'égaré). J'aurais dû copier et coller au lieu de retaper. J'ai maintenant corrigé l'info. –

1

Cela peut aider dans le cas où vous avez un vrai n-ième problème de précision racine, mais mon experiance est que le builtin Math.pow (double, int) est plus précis:

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