Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-如何避免在gmpy2中以y为基数**以y为基数记录x的差异_Python_Logarithm_Gmpy - Fatal编程技术网

Python-如何避免在gmpy2中以y为基数**以y为基数记录x的差异

Python-如何避免在gmpy2中以y为基数**以y为基数记录x的差异,python,logarithm,gmpy,Python,Logarithm,Gmpy,下面的代码举例说明了我的问题,它不会发生在10次方10和10次方11之间,但会发生在代码及其以上给出的示例中 我看不出我的代码中哪里没有正确处理原始值的检索。也许我错过了一些简单的事情 我需要确保我可以从log x中恢复各种基础的x。与依赖于库函数(如gmpy2)不同,是否有任何反向反日志算法可以保证,对于2**log2(x),它将给出x 我可以看到如何直接开发日志,但不知道如何返回,例如,泰勒级数需要很多术语。。。和@dan04回复。代码如下 from gmpy2 import gcd, fl

下面的代码举例说明了我的问题,它不会发生在10次方10和10次方11之间,但会发生在代码及其以上给出的示例中

我看不出我的代码中哪里没有正确处理原始值的检索。也许我错过了一些简单的事情

我需要确保我可以从
log x
中恢复各种基础的
x
。与依赖于库函数(如
gmpy2
)不同,是否有任何反向反日志算法可以保证,对于
2**log2(x)
,它将给出
x

我可以看到如何直接开发日志,但不知道如何返回,例如,泰勒级数需要很多术语。。。和@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')

只要设置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')

正如大家所承认的,阿圭解决了我的问题。 我没有考虑需要超过15位的精度。 对另一个问题的回答涵盖了这一点。

阿圭解决了我的问题,这是公认的。 我没有考虑需要超过15位的精度。 对另一个问题的回答涵盖了这一点。

注意:我维护了
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
注意:我维护
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

首先,我不知道你是如何让
random.randint
处理这些限制的。它在我的机器上不起作用。。。但无论如何,我怀疑这与浮点运算精度有关。我认为你是对的,在这种情况下,我的问题是,我如何在python或gmpy2或其他库中绕过它?我可以通过中描述的方法获得反日志,因此对于日志2,它不是通过自然日志,而是直接计算日志基数2。首先,我不知道你是如何让
random.randint
处理这些限制的。它在我的机器上不起作用。。。但无论如何,我怀疑这与浮点运算精度有关。我想你是对的,在这种情况下,我的问题是,我如何在python或gmpy2或其他库中绕过它?我可以通过中描述的方法获取反日志,因此对于日志2,它不是通过自然日志,而是直接计算日志库2。好的,谢谢,这适用于十进制,log10,但通常适用于“各种基数”,即不同的基数,除自然对数以外的任何整数基数,例如2,以恢复x?@ocopa-请参阅我关于不同基数的编辑。只要使用log10(x)/log10(base)就可以了。是的,我知道这一点,但我正在努力找出为什么我从gmpy2得到了错误的答案,以及底层代码是什么。gmpy2似乎在幕后使用log base e,或者我们认为可能存在浮点精度问题。在我发布了一些有用的参考资料后,我会很快将其标记为已回答。有用的对数参考资料在Dan04处回答在log0处回答在OK,谢谢,这适用于十进制,log10,但通常适用于“各种基数”,即不同的基数,除自然对数以外的任何整数基数,例如2,要恢复x?@ocopa-请参阅我对不同基础的编辑。只要使用log10(x)/log10(base)就可以了。是的,我知道这一点,但我正在努力找出为什么我从gmpy2得到了错误的答案,以及底层代码是什么。gmpy2似乎在幕后使用log base e,或者我们认为可能存在浮点精度问题。在我发布了一些有用的参考资料后,我会很快将其标记为已回答。有用的对数参考资料在Dan04处回答在log0处回答