Python - 如何避免 gmpy2 中 x 的基数 y**log 基数 y 的差异
Python - How to avoid discrepancy of base y**log base y of x, in gmpy2
以下代码示例了我的问题,该问题不会发生在 10 的 10 次方和 10 的 11 次方之间,但对于代码中及上方给出的示例会发生。
我看不出我的代码中哪里没有正确处理原始值的检索。可能是我错过了一些简单的东西。
我需要确保我可以从 log x
恢复 x
的各种基地。而不是依赖于诸如 gmpy2
之类的库函数,是否有任何反向 anti-log 算法可以保证说 2**log2(x)
它将给出 x
.
我可以看到如何直接开发一个日志,但没有如何返回,例如,泰勒级数需要很多项... How can I write a power function myself?和@dan04 回复。代码如下。
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()
只要设置decimal模块精度即可,通常建议使用Decimal数据类型
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')
对于不同的基数,您可能需要使用对数公式:
x2 = Decimal.log10(x) / Decimal.log10(Decimal('2'))
e2 = 2**x2
e2 - x
#outputs: Decimal('3.9E-978')
Aguy 解决了我的问题,这是公认的。
我没有考虑到需要超过 15 位的精度。
This answer to another question涵盖了这一点。
注意:我维护 gmpy2
库。
在您的示例中,您使用的是 decimal
模块中的 getcontext()
。您没有更改 gmpy2
使用的精度。由于gmpy2
的默认精度是53位,而你的x值需要69位,所以预计你会出错。
这是您的示例的更正版本,说明了随着精度的提高累积误差如何变化。
import gmpy2
def rint(n):
gmpy2.get_context().precision = n
# check accuracy of exp(log(x))
e = gmpy2.exp(1)
l2 = gmpy2.log(2)
l10 = gmpy2.log(10)
x = 481945878080003762113
# logs to different bases
x2 = gmpy2.log2(x)
x10 = gmpy2.log10(x)
xe = gmpy2.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("precision", n, "value", x, "error sum", error)
for n in range(65, 81):
rint(n)
这是结果。
precision 65 value 481945878080003762113 error sum 1061
precision 66 value 481945878080003762113 error sum 525
precision 67 value 481945878080003762113 error sum -219
precision 68 value 481945878080003762113 error sum 181
precision 69 value 481945878080003762113 error sum -79
precision 70 value 481945878080003762113 error sum 50
precision 71 value 481945878080003762113 error sum -15
precision 72 value 481945878080003762113 error sum -14
precision 73 value 481945878080003762113 error sum 0
precision 74 value 481945878080003762113 error sum -2
precision 75 value 481945878080003762113 error sum 1
precision 76 value 481945878080003762113 error sum 0
precision 77 value 481945878080003762113 error sum 0
precision 78 value 481945878080003762113 error sum 0
precision 79 value 481945878080003762113 error sum 0
precision 80 value 481945878080003762113 error sum 0
以下代码示例了我的问题,该问题不会发生在 10 的 10 次方和 10 的 11 次方之间,但对于代码中及上方给出的示例会发生。
我看不出我的代码中哪里没有正确处理原始值的检索。可能是我错过了一些简单的东西。
我需要确保我可以从 log x
恢复 x
的各种基地。而不是依赖于诸如 gmpy2
之类的库函数,是否有任何反向 anti-log 算法可以保证说 2**log2(x)
它将给出 x
.
我可以看到如何直接开发一个日志,但没有如何返回,例如,泰勒级数需要很多项... How can I write a power function myself?和@dan04 回复。代码如下。
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()
只要设置decimal模块精度即可,通常建议使用Decimal数据类型
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')
对于不同的基数,您可能需要使用对数公式:
x2 = Decimal.log10(x) / Decimal.log10(Decimal('2'))
e2 = 2**x2
e2 - x
#outputs: Decimal('3.9E-978')
Aguy 解决了我的问题,这是公认的。
我没有考虑到需要超过 15 位的精度。
This answer to another question涵盖了这一点。
注意:我维护 gmpy2
库。
在您的示例中,您使用的是 decimal
模块中的 getcontext()
。您没有更改 gmpy2
使用的精度。由于gmpy2
的默认精度是53位,而你的x值需要69位,所以预计你会出错。
这是您的示例的更正版本,说明了随着精度的提高累积误差如何变化。
import gmpy2
def rint(n):
gmpy2.get_context().precision = n
# check accuracy of exp(log(x))
e = gmpy2.exp(1)
l2 = gmpy2.log(2)
l10 = gmpy2.log(10)
x = 481945878080003762113
# logs to different bases
x2 = gmpy2.log2(x)
x10 = gmpy2.log10(x)
xe = gmpy2.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("precision", n, "value", x, "error sum", error)
for n in range(65, 81):
rint(n)
这是结果。
precision 65 value 481945878080003762113 error sum 1061
precision 66 value 481945878080003762113 error sum 525
precision 67 value 481945878080003762113 error sum -219
precision 68 value 481945878080003762113 error sum 181
precision 69 value 481945878080003762113 error sum -79
precision 70 value 481945878080003762113 error sum 50
precision 71 value 481945878080003762113 error sum -15
precision 72 value 481945878080003762113 error sum -14
precision 73 value 481945878080003762113 error sum 0
precision 74 value 481945878080003762113 error sum -2
precision 75 value 481945878080003762113 error sum 1
precision 76 value 481945878080003762113 error sum 0
precision 77 value 481945878080003762113 error sum 0
precision 78 value 481945878080003762113 error sum 0
precision 79 value 481945878080003762113 error sum 0
precision 80 value 481945878080003762113 error sum 0