7

x' is the nth root of y if x' is the largest integer such that x^n <= y. x, x' and y are all integers. Is there any efficient way to compute such nth root? I know this is usually done by nth root algorithm, but the difficulty here is everything is integer because I'm working with an embedded system.

BTW, I've even tried to binary search from 1 to y to identify largest x such that x^n <= y, but it does not work since x^n overflows easily especially when n is large.

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
sinoTrinity
  • 1,125
  • 2
  • 15
  • 27
  • 10
    If x^n overflows, how are you storing y? – Thomas Sep 13 '11 at 20:05
  • I'm not sure I fully understand the question, given n and y you're looking for x and x' such that x^n <= y <= x'^n ? (x and x' are respectively the largest and smalest integers) – Ricky Bobby Sep 13 '11 at 20:26
  • @Thomas I'm working with maximum of 4 bytes unsigned integer. Say y is 2 ^ 10 and n is 4. My naive algorithm tries all numbers from 1 to 2 ^ 10. When x is 2 ^ 8, oops, (2 ^ 8) ^ 4 = 2 ^ 32, overflow! – sinoTrinity Sep 14 '11 at 01:36
  • @Ricky Bobby I'm looking for the largest integer x such that x^n <=y – sinoTrinity Sep 14 '11 at 01:38

3 Answers3

10

Store a table for given y of the maximum x such that x^y does not overflow. Use these values for binary search; that way, no more overflow and a neat algorithm that will work as long as x and n have the same (integer) type. Right?

Note: for y > 32, the maximum value for x is 2 for 32-bit integers... in other words, your table will be the same size as the number of bits in integers your system understands, approximately.

Patrick87
  • 27,682
  • 3
  • 38
  • 73
  • Excellent solution. Sparse on memory, as efficient as it gets. – Thomas Ahle Sep 13 '11 at 21:54
  • @Patrick87 Your solution may not work because for a given n, to find the maximum x such that x^n does not overflow, as you suggest, is equivalent to let y be (2^32 - 1) and solve the original problem I raised. (I'm working with 4 byte unsigned integers) – sinoTrinity Sep 14 '11 at 01:46
  • @sinoTrinity: not sure what you're talking about. For 4-byte (say unsigned) integers, the table would look like 2->~2^16 3->~2^11, 4->~2^8, ..., 32->2^1, >33->1... then binary search until you hit the cap. Provided n is a valid 32 bit unsigned int, choosing x less than the cap for given x will ensure x^y doesn't overflow. Maybe I misunderstand your problem. – Patrick87 Sep 14 '11 at 02:13
  • Also, you precompute this table. Sorry if this wasn't initially clear. As in, make them constants in your program. – Patrick87 Sep 14 '11 at 02:14
  • Also, it looks like I'm calling Y what you called N, and vice versa... Sorry if this is confusing. – Patrick87 Sep 14 '11 at 02:16
2

Are you looking for integer roots only? Or do you want to know that the 5th root of 34 is 2.024...? Or is "2" a sufficient answer? If you want the decimal places, you'll have to do some kind of floating point or fixed point math.

You should read Computing principal roots, and note what it says about the first Newton approximate. If an error of about 0.03% is close enough, I'd suggest you go with this. You'd probably want to build a table that you can use to do the initial approximations. This table isn't as large as it sounds. The cube root of 2^32 is only about 1,626. You can easily compute the squares, and it's easy to generate x^n if you can generate x^2 and x^3. So doing the approximations is pretty easy.

Another possibility is to build yourself a table of roots and use some kind of interpolation. Again, that table wouldn't have to be very large if you treat the square root as a special case. The 5th root of 2^32 is less than 100, so you're talking a pretty small table to get a pretty large range of roots.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
1

I think the best method is to use the Newton-Raphson method from the Wikipedia article.

A good starting value can be computed from the bit length of the input divided by n. In each iteration you use integer division that rounds down. Iterate until you have found a value x such that x^n <= y < (x+1)^n.

You have to be careful to avoid overflow. As the other answer says, you can use a table of the maximal root for n < bit size to do that (for greater n the answer is always 1, except for y = 0).

starblue
  • 55,348
  • 14
  • 97
  • 151