2009-10-10 5 views
5

Wenn ich versuche, die N-te Wurzel einer kleinen Zahl mit C# zu nehmen, bekomme ich eine falsche Nummer.N-te Wurzel der kleinen Zahl gibt ein unerwartetes Ergebnis in C zurück #

Zum Beispiel, wenn ich versuche, die dritte Wurzel von 1.07 zu nehmen, bekomme ich 1, was eindeutig nicht wahr ist.

Hier ist der genaue Code, den ich verwende, um die dritte Wurzel zu bekommen.

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

Wie löse ich dieses Problem?

Ich würde vermuten, dass dies eine Gleitkommaarithmetik ist, aber ich weiß nicht, wie ich damit umgehen soll.

+2

Es ist eigentlich eine Integer-Division Problem. 1/3 wird als Integer ausgewertet mit dem Ergebnis, dass die Division 0 ist. Damit nimmst du wirklich 1,07 zur 0. Potenz, die 1 ist. – tvanfosson

Antwort

9

Ich bin ziemlich sicher, dass der "genaue Code", den Sie geben, nicht kompiliert.

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

Der Aufruf von toString ist an der falschen Verschachtelungsebene muss, ToString sein, und (1/3) ist Integer-Division, die wahrscheinlich das eigentliche Problem ist, Sie haben. (1/3) ist 0 und alles zur nullten Potenz ist 1. Du brauchst (1.0/3.0) oder (1d/3d) oder ...

+0

Lieber Captain sarkastisch. Entschuldigung wegen der unangebrachten). Ich hätte kopieren und einfügen statt neu tippen. Ich habe jetzt die Info korrigiert. Danke für die ausgezeichnete Antwort! –

+0

ps. hat gut funktioniert –

+6

Normalerweise würde ich nicht auf einen offensichtlichen Syntaxfehler hinweisen, aber irgendwie fühlte ich mich verpflichtet, da Sie sich bemüht haben, das Wort "exakt" zu verwenden. Froh, dass es geholfen hat. –

13

C# ist die 1 und die 3 als ganze Zahlen zu behandeln, müssen Sie folgendes tun:

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

oder

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

Es ist eigentlich interessant, weil die implizite Erweiterung Umwandlung macht Sie zu einem machen Fehler.

3

Das Wichtigste zuerst: Wenn das der genaue Code ist re verwenden, ist es wahrscheinlich etwas falsch mit Ihrem Compiler :-)

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

wird (1/3) .toString() auswerten zuerst versuchen und 1,07 an die Macht dieser Zeichenfolge zu erhöhen.

Ich denke du meinst:

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

Was das Problem (1/3) als Integer-Division behandelt wird Rückkehr 0 und n ist 1 für alle Werte von n.

Sie müssen es zu einer Gleitkommadivision mit etwas wie 1.0/3.0 erzwingen.

+0

Sorry über die fehlplatziert). Ich hätte kopieren und einfügen statt neu tippen. Ich habe jetzt die Info korrigiert. –

1

Dies Fall kann helfen, haben Sie eine echte n-te Wurzel Präzision Problem, aber meine experiance ist, dass die eingebaute Math.Pow (double, int) ist präziser:

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