I need to find a greatest number, x for given y and n such that x ^ y <= n
Here n can be very large number - 1 <= n <= 10^10 and 1 <= y <= 10^5
for example :
for y = 5 and n = 1024
x ^ 5, then x = 4 (4 ^ 5 = 1024)
for y = 5 and n = 480
x ^ 5 , then x = 3 (3 ^ 5 = 243, 4 ^ 5 = 1024) - selecting lowest one, so x = 3
i have written a small program, But i want more efficient technique because n and y can be very large.
def get(y, n):
x = 1
while x ** y <= n:
x += 1
return x - 1
Using a multiple-precision arithmetic library, such as gmpy2's
iroot
.This is simply an integer n-th root algorithm. It should be fast and correct even for huge numbers (something that floats cannot guarantee in the general case).
The second value returned is a boolean which indicates if the root is exact or not.
you can use binary search on integer to move from your
O(x)
toO(log(x))
if you apply floating math then:your example
n=400
andy=5
is like this:of coarse for big
n
will this not work with basic floating types. In such case either use bin search on big integers or implement your own bigint pow if you do not have it already at your disposal. Anyway both approaches are described here:[edit1]
after absorbing your comments:
I would use binary search. You need to use at least
ceil(log2(10^10))=34 bit
variables for this so unsigned 64 bitQWORD
it is. if you do not have such variables you need to implement it from lower bit width variables first.The binary search mask will be:
so you first need to implement
pow
and thenroot
adapting code from linked answer here is C++ result:for those of you that have just 32 bit arithmetics and have lover limit
n<2^32
change the defines to:or use any other variable type you got at your disposal. The
T
is your data-typeT_MSB
is MSB bit set andT_bits
is used bit count.If you use:
it will return
3
. You can use your**
instead ofpow
I can not as my compiler does not recognize**
operator. Now to explanation of binary searchlet assume your example. You start with
x=1
then testx=2
thenx=3
and so on until you crossx^y>=n
so in reality you had checkedpow(n,1/y)
values. if we usen=10000, y=2
that will lead to100
tests.The binary search does not increment but set individual bits instead.
10000
has 14 bits soceil(14/y)=7
so the process will be:leading to only
7
tests instead of your naive100
.