ocopa ocopa - 4 months ago 11
Python Question

Python - How to avoid discrepancy of base y**log base y of x, in gmpy2

The Following code examples my problem which does not occur between 10 power 10 and 10 power 11, but does for the example given in code and above it.

I can't see where in my code I am not properly handling the retrieval of the original value. May be I have just missed something simple.

I need to be sure that I can recover

x
from
log x
for various bases. Rather than rely on a library function such as
gmpy2
, is there any reverse anti-log algorithm which guarantees that for say
2**log2(x)
it will give
x
.

I can see how to directly develop a log, but not how to get back, eg, Taylor series needs a lot of terms... How can I write a power function myself? and @dan04 reply. Code follows.

from gmpy2 import gcd, floor, next_prime, is_prime
from gmpy2 import factorial, sqrt, exp, log,log2,log10,exp2,exp10
from gmpy2 import mpz, mpq, mpfr, mpc, f_mod, c_mod,lgamma
from time import clock
import random
from decimal import getcontext
x=getcontext().prec=1000 #also tried 56, 28
print(getcontext())

def rint():#check accuracy of exp(log(x))
e=exp(1)
l2=log(2)
l10=log(10)
#x=random.randint(10**20,10**21) --replaced with an actual value on next line
x=481945878080003762113
# logs to different bases
x2=log2(x)
x10=log10(x)
xe=log(x)
# logs back to base e
x2e=xe/l2
x10e=xe/l10
#
e2=round(2**x2)
e10=round(10**x10)
ex=round(e**xe)
#
ex2e=round(2**x2e)
ex10e=round(10**x10e)
error=5*x-(e2+e10+ex+ex2e+ex10e)
print(x,"error sum",error)
#print(x,x2,x10,xe)
#print(x2e,x10e)
print(e2,e10,ex)
print(ex2e,ex10e)
rint()

Answer

As long as you set the decimal module accuracy, the usual suggestion is to use Decimal datatype

from decimal import Decimal, getcontext

getcontext().prec = 1000

# Just a different method to get the random number:
x = Decimal(round(10**20 * (1 + 9 * random.random()))) 

x10 = Decimal.log10(x)
e10 = 10**x10

e10 - x
#outputs: Decimal('5.2E-978')

For different bases you may want to use the logarithmic formula:

x2 = Decimal.log10(x) / Decimal.log10(Decimal('2'))
e2 = 2**x2

e2 - x
#outputs: Decimal('3.9E-978')
Comments