10

From http://msdn.microsoft.com/en-us/library/system.math.pow.aspx

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

Math.Pow takes doubles as arguments, yet here we are passing in ints.

Question: Is there any danger of floating point rounding errors if there is an implicit conversion to double happening?

If yes, it is better to use something like:

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;
}
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Dave Mateer
  • 6,588
  • 15
  • 76
  • 125
  • Related question: http://stackoverflow.com/questions/383587/how-do-you-do-integer-exponentiation-in-c Some good reading in that question and related links – dash Jun 25 '12 at 20:22
  • See also: http://stackoverflow.com/questions/936541/math-pow- – dash Jun 25 '12 at 20:28
  • And [this one](http://stackoverflow.com/questions/4297454/c-sharp-math-pow-is-not-calculating-correctly) on rounding errors. – Anders Gustafsson Jun 25 '12 at 20:32
  • Your first link dash is a good one - thats where I initially got my IntPow code from. – Dave Mateer Jun 25 '12 at 20:48

4 Answers4

8

In your special case, when you are calculating 2 to the power x, you can use a simple left shift. This would simplify your code to:

public static int TwoPowX(int power)
{
    return (1<<power);
}
user5072377
  • 81
  • 1
  • 1
  • And in floating-point, powers of two can be trivially calculated with `ldexp`. Which .NET doesn't have, but is pretty easy to write using `BitConverter.Int64BitsToDouble`. – Ben Voigt Jul 15 '17 at 16:29
5

No, there's no possibility of rounding error caused by the conversion to double. double can exactly represent all integers which fall in the domain of the power function.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
4

Yes, there is an implicit conversion to double happening, and yes there is a possibility of floating point rounding errors as a result.

As to whether it's worth using the alternate method you propose, that's specific to the application. Is a floating point rounding error entirely unacceptable? Will you be using numbers that fit within int32 (it doesn't take a whole lot for powers to overflow)?

Servy
  • 202,030
  • 26
  • 332
  • 449
  • 2
    floating point rounding error when converting int to double? please write more on that. – Mare Infinitus Jun 25 '12 at 20:24
  • 1
    It's not just converting an int to a double, it's converting an int to a double and then doing stuff with it. As soon as you start performing any operations (add/multiply/whatever) there is at least a possibility of rounding errors. Since raising to a power is likely to be broken up into a number of add/multiplies, it increases the probability and magnitude of floating point errors. – Servy Jun 25 '12 at 20:27
  • you mean as they exist with any IEEE 754 number? – Mare Infinitus Jun 25 '12 at 20:40
-1
public static int IntPow(int number, uint power)
        {
            int result = 1;
            for (int i = 0; i < power; i++)
            {
                result *= number;
            }
            return result;
        }

for readability!

Dave Mateer
  • 6,588
  • 15
  • 76
  • 125
  • There's a reason for the extra code -- this answer is `O(power)`, while the code in the question if `O(log(power))`. – Ben Voigt Jun 25 '12 at 21:03