Math.Pow taking an integer value
Asked Answered
E

4

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;
}
Encrinite answered 25/6, 2012 at 20:17 Comment(4)
Related question: #384087 Some good reading in that question and related linksJacindajacinta
See also: https://mcmap.net/q/111344/-math-pow-vs-multiply-operator-performanceJacindajacinta
And this one on rounding errors.Jannelle
Your first link dash is a good one - thats where I initially got my IntPow code from.Encrinite
W
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)?

Wallpaper answered 25/6, 2012 at 20:20 Comment(3)
floating point rounding error when converting int to double? please write more on that.Rowlandson
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.Wallpaper
you mean as they exist with any IEEE 754 number?Rowlandson
W
9

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);
}
Wordbook answered 2/7, 2015 at 6:9 Comment(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.Fomalhaut
F
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.

Fomalhaut answered 25/6, 2012 at 21:2 Comment(0)
W
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)?

Wallpaper answered 25/6, 2012 at 20:20 Comment(3)
floating point rounding error when converting int to double? please write more on that.Rowlandson
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.Wallpaper
you mean as they exist with any IEEE 754 number?Rowlandson
E
-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!

Encrinite answered 25/6, 2012 at 21:0 Comment(1)
There's a reason for the extra code -- this answer is O(power), while the code in the question if O(log(power)).Fomalhaut

© 2022 - 2024 — McMap. All rights reserved.