打印Python和C++时的精度差异加倍

nh2*_*nh2 14 c++ python floating-point double

我现在惊叹于此:

C++ 11

#include <iostream>
#include <iomanip>
#include <limits>

int main()
{
  double d = 1.305195828773568;
  std::cout << std::setprecision(std::numeric_limits<double>::max_digits10) << d << std::endl;
  // Prints  1.3051958287735681
}
Run Code Online (Sandbox Code Playgroud)

蟒蛇

>>> repr(1.305195828773568)
'1.305195828773568'
Run Code Online (Sandbox Code Playgroud)

发生了什么,为什么C++中的额外1?

到目前为止,我认为C++和Python使用相同的64位IEEE双打; 两个格式化函数都应该打印完整的精度.

hir*_*ist 10

你可以强制python打印1(以及更多以下数字):

print('{:.16f}'.format(1.305195828773568))
# -> 1.3051958287735681
Run Code Online (Sandbox Code Playgroud)

来自https://docs.python.org/2/tutorial/floatingpoint.html:

>>> 7205759403792794 * 10**30 // 2**56
100000000000000005551115123125L
Run Code Online (Sandbox Code Playgroud)

在Python 2.7和Python 3.1之前的版本中,Python将此值四舍五入为17位有效数字,给出"0.10000000000000001".在当前版本中,Python显示一个基于最小小数的值,该小数正确地回滚到真正的二进制值,结果只是'0.1'.

"打印全精度"很难做到:全精度是多少?浮点数的表示是二元的; 只能得到2的幂的分数(完全精确); 大多数小数部分不能在基数2中精确表示.

但是对于python和c ++,内存中的float将是相同的; 它只是字符串表示不同.

  • 最接近的IEEE 64位二进制浮点数的精确值是1.3051958287735681008001620284630917012691497802734375 - 绝对不能代表实际输入. (2认同)

eri*_*rip 2

摘自这个问题的答案:

IEEE 754 浮点数以二进制形式完成。没有从给定位数到给定十进制位数的精确转换。3 位可以保存从 0 到 7 的值,4 位可以保存从 0 到 15 的值。从 0 到 9 的值大约需要 3.5 位,但这也不精确。

IEEE 754 双精度数占用 64 位。其中,52 位专用于有效数(其余的是符号位和指数)。由于尾数(通常)已标准化,因此隐含第 53 位。

现在,给定 53 位和每个数字大约 3.5 位,简单除法得出 15.1429 位的精度。但请记住,每个十进制数字 3.5 位只是一个近似值,而不是一个完全准确的答案。

您提供的 15 位数字后的这种奇怪现象.1429可能是添加 1 的罪魁祸首。

无论如何,Python 在他们的网站上写了这样的内容:

从历史上看,Python 提示符和内置repr()函数会选择 17 位有效数字,即 0.10000000000000001。从 Python 3.1 开始,Python(在大多数系统上)现在能够选择其中最短的一个并简单地显示 0.1。