2012-06-25 8 views
8

Von http://msdn.microsoft.com/en-us/library/system.math.pow.aspxMath.Pow einen ganzzahligen Wert

int value = 2; 
for (int power = 0; power <= 32; power++) 
    Console.WriteLine("{0}^{1} = {2:N0}", 
         value, power, (long) Math.Pow(value, power)); 

Einnahme nimmt Math.Pow verdoppelt sich als Argumente, aber hier passieren wir in ints.

Frage: Besteht die Gefahr von Gleitkomma-Rundungsfehlern, wenn eine implizite Konvertierung in Doppelhappen vorliegt?

Wenn ja, es ist besser, etwas zu verwenden, wie:

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

Verwandte Frage: http://stackoverflow.com/questions/383587/how-do-you-do-integer-exponentiation-in-c Einige gute Lektüre in dieser Frage und verwandte Verbindungen – dash

+0

Sehen Sie auch: http://stackoverflow.com/questions/936541/math-pow- – dash

+0

Und [dieses] (http://stackoverflow.com/questions/4297454/c-sharp-math-pow-is - nicht korrekt berechnen - auf Rundungsfehler. –

Antwort

3

Ja, es gibt eine implizite Konvertierung geschieht zu verdoppeln, und ja, es gibt eine Möglichkeit, Punkt Rundungsfehler als Folge des Schwebens.

Ob es sich lohnt, die von Ihnen vorgeschlagene alternative Methode zu verwenden, ist für die Anwendung spezifisch. Ist ein Fließkomma-Rundungsfehler völlig inakzeptabel? Werden Sie Zahlen verwenden, die in int32 passen (es braucht nicht viel, bis die Kräfte überlaufen)?

+2

Fließkomma-Rundungsfehler beim Konvertieren von int in double? Bitte schreib mehr darüber. –

+1

Es wird nicht nur ein int in ein double umgewandelt, sondern ein int in ein double umgewandelt und dann damit umgegangen. Sobald Sie mit der Ausführung von Operationen beginnen (add/multiplizieren/was auch immer), besteht zumindest die Möglichkeit von Rundungsfehlern. Da das Erhöhen auf eine Potenz wahrscheinlich in eine Anzahl von add/multiplies aufgeteilt wird, erhöht es die Wahrscheinlichkeit und Größe von Gleitkommafehlern. – Servy

+0

Sie meinen, wie sie mit jeder IEEE 754 Nummer existieren? –

-1
public static int IntPow(int number, uint power) 
     { 
      int result = 1; 
      for (int i = 0; i < power; i++) 
      { 
       result *= number; 
      } 
      return result; 
     } 

für Lesbarkeit!

+0

Es gibt einen Grund für den zusätzlichen Code - diese Antwort lautet "O (power)", während der Code in der Frage "O (log (power))" ist. –

5

Nein, es gibt keine Möglichkeit für Rundungsfehler, die durch die Konvertierung in double verursacht werden. double kann genau alle ganzen Zahlen repräsentieren, die in den Bereich der Potenzfunktion fallen.

5

In Ihrem speziellen Fall, wenn Sie 2 zur Macht x berechnen, können Sie eine einfache Linksverschiebung verwenden. Dies würde vereinfachen Ihren Code:

public static int TwoPowX(int power) 
{ 
    return (1<<power); 
} 
+0

Und im Gleitkomma können Zweierpotenzen mit 'ldexp' trivial berechnet werden. Was .NET nicht hat, ist aber ziemlich einfach mit 'BitConverter.Int64BitsToDouble' zu ​​schreiben. –

Verwandte Themen