C # function isPowerOf

I have the following function:

static bool isPowerOf(int num, int power) { double b = 1.0 / power; double a = Math.Pow(num, b); Console.WriteLine(a); return a == (int)a; } 

I inserted a print function for analysis.

If I call the function:

 isPowerOf(25, 2) 

It returns true, since 5^2 is 25. But if I call 16807, that is, 7^5 , the following way:

 isPowerOf(16807, 5) 

In this case, it prints "7", but a == (int)a returns false.

You can help? Thanks!

+7
source share
4 answers

Try using a small epsilon for rounding errors:

 return Math.Abs(a - (int)a) < 0.0001; 

As Harold suggested, it is better to round if a turns out to be slightly less than an integer value, for example 3.99999:

 return Math.Abs(a - Math.Round(a)) < 0.0001; 
+6
source

Comparisons have been proposed that fix the problem, but in fact the problem is that there should not be a floating point at all. You want an exact answer to the question regarding integers, and not approximation of calculations performed on inherently inaccurate measurements.

So how else can this be done?

The first thing that comes to mind is a hoax:

 double guess = Math.Pow(num, 1.0 / power); return num == exponentiateBySquaring((int)guess, power) || num == exponentiateBySquaring((int)Math.Ceil(guess), power); // do NOT replace exponentiateBySquaring with Math.Pow 

It will work as long as the guess is less than 1. But I cannot guarantee that it will always work on your inputs, because this condition is not always fulfilled.

So here’s what comes to mind: binary search (the option where you first look for the upper bound) for base in exponentiateBySquaring(base, power) , for which the result is close to num . If and only if the closest answer is num (and they are both integers, so this comparison is pure), then num is the power degree. If there is no overflow (should not be), this should always work.

+5
source

If you are debugging the code, and then you can see it in the first comparison:

 isPowerOf(25, 2) 

a holds 5.0 Here 5.0 == 5 => That's why you get the true value

and in the second isPowerOf(16807, 5)

a holds 7.0000000000000009

and since 7.0000000000000009 != 7 =>, you become false. and Console.WriteLine (a) trims / rounds the double and shows only 7

This is why you need to compare the closest value, as in the Dani solution

+2
source

Math.Pow runs on double s, so rounding errors come into play when rooting. If you want to check that you have found the exact power:

  • execute Math.Pow as of now, extract the root
  • round result to the nearest integer
  • raise this integer to the power supplied and verify that you are getting the goal. Math.Pow will be accurate for numbers in the int range when raised to integer degrees
+2
source

All Articles