Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pow() raising to floats

Tags:

python

math

Why does raising to an integer expressed as a floating point number give different results to raising the same number in its integer form?

E.g.:

>>> pow(10,25)%195
10L
>>> pow(10,25.0)%195
64.0

I've tried using mpmath's power() instead, but get the exact same numbers - and error - as the second form.

How can I raise to very large non-integer powers and perform mod on them (e.g. steps taken to perform RSA-like logic using pure math) in Python?

like image 303
Will Avatar asked Sep 21 '13 16:09

Will


2 Answers

For integers, you can use the 3-argument form of pow:

pow(10, 25, 195)

Your problem here stems from loss of precision in floats. You need to use decimal.Decimals here:

>>> from decimal import Decimal
>>> pow(10, Decimal('25.0')) % 195
Decimal('10')
like image 125
Eric Avatar answered Oct 12 '22 08:10

Eric


To answer your question, because floats in Python are IEEE754 floats and have limited precision.

>>> int(10**25.0)
10000000000000000905969664L

As you can see, the answer is close but incorrect.

How can I raise to very large non-integer powers and perform mod on them (e.g. steps taken to perform RSA-like logic using pure math) in Python?

This is my suggestion using x^(a+b) = x^a * x^b:

def powmod_f(base, exponent, mod):
    return (pow(base, int(exponent), mod) * (base ** (exponent % 1))) % mod

This only works with an integer base however, if your base is a float as well you're going to have to implement a powmod algorithm yourself.

like image 43
orlp Avatar answered Oct 12 '22 09:10

orlp