提问人: 提问时间:9/22/2021 更新时间:7/24/2023 访问量:2237
欧拉-马斯切罗尼常数
Euler-Mascheroni Constant
问:
在编程中,我只使用整数。但这次是进行一些计算。我需要计算欧拉-马斯切罗尼常数。最多小数点后 n 位。{虽然对我来说已经足够了。γ
n ∈ [30, 150]
- [x] = gif(x) = 数学地板(x)
但是,我怀疑精确的数值算法
我需要使用 Python 获得更高的准确性。
答:
4赞
Stef
9/22/2021
#1
在法语维基百科的讨论页面中,小数点后6位的近似值:
import math as m
EulerMascheroniApp = round( (1.-m.gamma(1+1.e-8))*1.e14 )*1.e-6
print(EulerMascheroniApp)
# 0.577216
这个常量也可以在 sympy 模块中使用,名称为:EulerGamma
>>> import sympy
>>> sympy.EulerGamma
EulerGamma
>>> sympy.EulerGamma.evalf()
0.577215664901533
>>> - sympy.polygamma(0,1)
EulerGamma
>>> sympy.stieltjes(0)
EulerGamma
>>> sympy.stieltjes(0, 1)
EulerGamma
文档:
在最后一个文档链接中,您可以找到有关如何更精确地计算常量的更多信息(如果默认值不够)。.evalf()
如果您仍然想自己计算常数作为练习,我建议将结果与 sympy 常数进行比较,以检查准确性和正确性。
评论
0赞
Guinther Kovalski
9/22/2021
EulerMascheroniApp = round( (1.-m.gamma(1+1.e-8))*1.e14 )*1.e-6 中的精度如何提高?
0赞
Stef
9/22/2021
我尝试使用该功能,并获得了两个位置,但仅此而已:round
g = 0.57721566490153286060651209008240243104215933593992
g - round( (1.-m.gamma(1+1.e-8))*1.e14 )*1.e-6 # -3.350984670857926e-07
g - round( (1.-m.gamma(1+1.e-8))*1.e15 )*1.e-7 # 6.490153292570966e-08
g - round( (1.-m.gamma(1+1.e-8))*1.e16 )*1.e-8 # 3.4901532885989184e-08
g - round( (1.-m.gamma(1+1.e-8))*1.e17 )*1.e-9 # 3.390153280324881e-08
1赞
10/1/2021
@Stef 最后,我安装了sympy,可以接受你的回答😃。
1赞
Guinther Kovalski
9/22/2021
#2
您可以使用 python Decimal 内置模块来控制要使用的小数位数 (https://docs.python.org/2/library/decimal.html)。
a = 1/7
len(str(a))-2
Out[1] 17
使用 Decimal:
from decimal import *
getcontext().prec = 90 #90 decimals precision
a = Decimal(1) / Decimal(7)
len(str(a))-2
Out[2] 90
基本上:
n = 100000
Euler_Mascheroni = -Decimal(log(Decimal(n))) + sum([Decimal(1)/Decimal(i) for i in range(1,n)])
Euler_Mascheroni
Out[3] Decimal('0.577210664893199330073570099082905499710324918344701101627529415938181982282214')
最后,您可以“任意”提高精度:
from decimal import *
from math import log
def Euler_Mascheroni(n,nth_decimals = 80):
getcontext().prec = nth_decimals
SUM = Decimal(0)
for i in range(1,n):
SUM+=Decimal(1)/Decimal(i)
return -Decimal(log(Decimal(n))) + SUM
Euler_Mascheroni(100000000,nth_decimals = 120)
这给了:
Decimal('0.5772156599015311156682000509495086978690376512201034388184221886576113026091829254475798266636558124658249350393045066')
回答@Stef的意见
EM = Decimal(0.57721566490153286060651209008240243104215933593992)#reference taken from wikipedia
n = 100000000
Decimal(log(Decimal(n)))
getcontext().prec = 100
SUM = Decimal(0)
for i in range(1,n):
SUM+=Decimal(1)/Decimal(i)
EM - (SUM-Decimal(log(Decimal(n))))
会给
Decimal('5.00000174 ... 85E-9')
评论
0赞
Stef
9/22/2021
您的结果与从小数点后第 6 位开始不同:结果为 。我通过与维基百科上给出的 50 位值进行比较进行了检查,它也从小数点后第 6 位开始有所不同。因此,看起来调整模块 Decimal 的小数位数不足以修复近似误差。sympy.EulerGamma.evalf()
print(sympy.EulerGamma.evalf() - Euler_Mascheroni)
5.00000833358882e-6
0赞
Stef
9/22/2021
事实上,近似值比round( (1.-m.gamma(1+1.e-8))*1.e14 )*1.e-6
-Decimal(log(Decimal(n))) + sum([Decimal(1)/Decimal(i) for i in range(1,n)])
1赞
Stef
9/22/2021
另外,你用的是哪个?我曾经尝试过你的代码;您唯一的导入是 ,但 Module Decimal 没有 .我建议使用 而不是 ,以便读者可以更容易地弄清楚您正在使用哪些功能。log
math.log
from decimal import *
log
import decimal as d
from decimal import *
0赞
Guinther Kovalski
9/22/2021
你是对的,仅靠更多的小数点并不能解决问题,我们需要更多的迭代。A 通过改进编辑了我的答案。另外,我使用了数学日志。问题是注意获取常量的实际值,但使用任意(30 到 80 位小数)更高的精度来计算它。
2赞
Stef
9/22/2021
您使用 100000000 次迭代来获得 5 位小数精度。这是一个好兆头,表明该方法效率不高,需要更好的方法。只有当方法的精度优于浮点数的精度时,才需要使用 Decimal 而不是 float,而这远非手头的情况。
0赞
Joren
7/24/2023
#3
如果您使用的是 numpy,则可以使用 numpy.euler_gamma
:
>>> import numpy as np
>>> np.euler_gamma
0.5772156649015329
上一个:将双数转换为数字,反之亦然?
评论
decimal
fractions