Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate pow() with modulo for real numbers? [closed]

Tags:

python

vb.net

pow

I want to perform a power operation combined with a modulo. I have trouble performing this pow() function with real numbers.

This works fine for integers:

pow(2,6000,400) = 176

However, this returns an error with real numbers:

pow(1.4142, 6000, 400)

I have tried also the math.pow() function but it doesn't work either... how can I get this to work with real numbers ?

like image 627
Amy Avatar asked Sep 05 '25 03:09

Amy


1 Answers

The python function pow() accepts 2 or 3 arguments. In your case, pow(x,y,z) does x power y and applies a modulo z to the result. But the documentation is explicit:

If the second argument is negative, the third argument must be omitted. If z is present, x and y must be of integer types, and y must be non-negative.

So:

  • Your first call works fine, because the arguments comply with the requirements. Note that despite pow(2,6000) being a huge number, the result of the combined modulo operation can be calculated easily without overflow, by using properties on modular exponentiation of integers.

  • Your second call fails with an error, because the first argument is not an integer. The workaround would be to decompose your operation into pow(1.4142,6000) % 400, because modulo is defined for real numbers.
    Unfortunately, pow(1.4142,6000) is too big and causes an overflow error. This is because contrary to the python integers which are of unlimited range, real numbers are limited by the range of the C floating point encoding.

P.S.: I assumed that it's about python and not VB, because VB's pow() accepts only 2 arguments.

Edit: hint for a workaround

Here a little workaround that makes use of the fact that technically, a floating point number is not a mathematical real of unlimited precision, but a rational number. We can then make use of the numerator and denominator and use integer operations to master the huge numbers:

n=pow(14142,6000)         # take the first argument multiplied by a 10 exponent to make it an integer
d=pow(10000,6000)         # keep track of this 10 exponent
i=n//d                    # integer division to compute the integral value
r=n-d*i                   # remainder of the integer division 
precision=6               # precision 
f=r*pow(10,precision)//d  # keep the 6 most significant digits 
result=(i%400)+(f/pow(10,precision)) 

The result is 271.048181 to the 6th digit. I let you as an exercise the writing of a function that performs this in a less artisanal way.

like image 190
Christophe Avatar answered Sep 08 '25 23:09

Christophe