python - cpython _math.c 中的 ln2 const 值

标签 python cpython

我正在查看 git 中的 _math.c(第 25 行):

#if !defined(HAVE_ACOSH) || !defined(HAVE_ASINH)
static const double ln2 = 6.93147180559945286227E-01;
static const double two_pow_p28 = 268435456.0; /* 2**28 */

我注意到 ln2 值与 ln2 的 what wolframalpha 值不同。 (光头部分就是区别)

ln2 = 0.693147180559945286227(cpython)

ln2 = 0.6931471805599453094172321214581 (wolframalpha)

ln2 = 0.693147180559945309417232121458(维基百科)

所以我的问题是为什么会有差异?我错过了什么?

最佳答案

如 user2357112 所述,此代码来自 FDLIBM。这是为 IEEE-754 机器精心编写的,其中 C double 具有 53 位精度。它并不真正关心 2 的实际对数是多少,而是非常关心 log(2) 的最佳 53 位近似值。

要重现预期的 53 位精确值,17 decimal digits would have sufficed .

那么为什么他们改用 21 位十进制数字呢?我的猜测:21 位十进制数字是保证转换结果正确到 64 位精度所需的最少数字。如果编译器以某种方式决定将文字转换为 Pentium 的 80 位浮点格式(具有 64 位精度),那么这可能在当时是个问题。

因此他们显示了具有足够十进制数字的 53 位结果,以便如果将其转换为具有 64 位精度的二进制浮点格式,则尾随的 11 位 (=64-53) 将全部为零,从而确保它们从一开始就使用预期的 53 位值。

>>> import mpmath
>>> x = mpmath.log(2)
>>> x
mpf('0.69314718055994529')
>>> mpmath.mp.prec = 64
>>> y = mpmath.mpf("0.693147180559945286227")
>>> x == y
True
>>> y
mpf('0.693147180559945286227')

在英文中,xlog(2)的53位精确值,y是小数化后的结果将代码中的字符串转换为具有 64 位精度的二进制浮点格式。它们是相同的。

在当前的现实中,我希望所有编译器现在都将文字转换为 native IEEE-754 double 格式,精度为 53 位。

无论哪种方式,代码都会确保使用 log(2) 的最佳 53 位近似值。

关于python - cpython _math.c 中的 ln2 const 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48644767/

相关文章:

python - 为什么我可以在 Python 中访问看似任意的内存地址?

python - 查找给定范围内其除数之和具有完美平方的数字,并将它们与相关平方一起返回

python - 嵌套列表理解范围

python - 在另一个目录的脚本中运行时,Pyclbr readmodule 失败

python - 在 Python 中访问未知类型的 Protobuf 消息字段

python - 使用 pyflakes 插件运行 vim 时出错

Python Cassandra 驱动程序仅插入一条记录

python - 在 Django 查询集中加入以过滤它

python - Apache Spark按用户ID排序分区,并将每个分区写入CSV

python - 为什么 False 值 (0) 的字节数小于 True (1)?