Julia中的exp函数求值为0

时间:2016-08-08 06:11:42

标签: julia mpfr

我想计算并绘制Julia中波函数的概率密度。我写了一小段Julia代码来评估以下函数:

P = A^2 e^{-(\sqrt(Cm)/\hbar)x^2}

Julia(不完整)代码是:

set_bigfloat_precision(100)
A = 10
C = 5
m = BigFloat(9.10938356e-31)
ℏ = BigFloat(1.054571800e-34)
t = exp(-(sqrt(C * m) / ℏ))

我评估t的最后一行给出了0.000000000000...。我也尝试设置BigFloat的精度。没运气!我究竟做错了什么?帮助赞赏。

1 个答案:

答案 0 :(得分:6)

在评论中,Chris Rackauckas指出你输错了公式。我认为无论如何回答这个问题很有意思

让我们分解它,这样我们就可以看到我们正在筹集的东西:

A = 10
C = 5
m = BigFloat(9.10938356e-31)
h = BigFloat(1.054571800e-34)

z = -sqrt(C * m)/h
t = exp(z)

所以 z =-2.0237336022083455711032042949257e+19 非常粗略z=-2e19)

如此粗略t=exp(-2e19)(即t=1/((e^(2*10^19))) 这是一个非常小的数字。

考虑一下 exp(big"-1e+10") = 9.278...e-4342944820exp(big"-1e+18") = 2.233...e-434294481903251828

是的,朱莉娅说: exp(big"-2e+19) = 0.0000

exp(big"-2e+19)是一个非常小的数字。 这让我们充满了希望。数量非常少。

所以julia依赖于MPFR BigFloats 您可以尝试MPFR online。精度为8192,exp(-2e10)=0 同样的结果。

现在,这不是我们关心的精确度。 而是指数的范围。

MPFR使用的东西有点像IEEE样式的浮点数,其中精度是尾数的长度,然后你有一个指数。 2^exponent * mantissa

因此指数的范围有限制。

请参阅:MPFR docs:

  

功能:mpfr_exp_t mpfr_get_emin(void)   功能:mpfr_exp_t mpfr_get_emax(void)

     

返回浮点变量允许的(当前)最小和最大指数。 浮点变量的最小正值是提升到最小指数的2倍,最大值的形式(1 - epsilon)乘以2提升到最大指数,其中epsilon取决于关于所考虑变量的精度。

现在julia确实将这些设置为相当默认的MPFR编译允许的最大范围。我一直在挖掘MPFR来源,试图找到它的设置位置,但无法找到它。我相信它与Int64可以容纳的最大故障有关。

Base.MPFR.get_emin() = -4611686018427387903 =typemin(Int64)>>1 + 1

你可以调整它,但只能调整。

所以无论如何

0.5*big"2.0"^(Base.MPFR.get_emin()) = 8.5096913117408361391297879096205e-1388255822130839284

0.5*big"2.0"^(Base.MPFR.get_emin()-1) = 0.00000000000...

现在我们知道了

exp(x) = 2^(log(2,e)*x)

所以我们可以exp(z) = 2^(log(2,e)*z)
log(2,e)*z = -29196304319863382016
Base.MPFR.get_emin() = -4611686018427387903

因此指数(粗略-2.9e19)小于最小允许指数(大约-4.3e17)。 发生下溢。

因此,你的答案是为什么你得零。

可能(或可能不)使用Int128指数重新调整MPFR,但julia没有。

也许朱莉娅应该抛出一个下溢异常。 免费鼓励在Julia Bug Tracker上报告这个问题。