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

2024-10-03 06:28:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我现在很惊讶:

<强> 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
}

Python

^{pr2}$ 什么事,为什么C++中有1个额外的值?在

到目前为止,我认为C++和Python在引擎盖下使用相同的64位IEEE双倍;两种格式函数都应该打印完整的精度。在


Tags: includemainprintsmaxintstddoubleiostream
3条回答

摘自对this question的回答:

IEEE 754 floating point is done in binary. There's no exact conversion from a given number of bits to a given number of decimal digits. 3 bits can hold values from 0 to 7, and 4 bits can hold values from 0 to 15. A value from 0 to 9 takes roughly 3.5 bits, but that's not exact either.

An IEEE 754 double precision number occupies 64 bits. Of this, 52 bits are dedicated to the significand (the rest is a sign bit and exponent). Since the significand is (usually) normalized, there's an implied 53rd bit.

Now, given 53 bits and roughly 3.5 bits per digit, simple division gives us 15.1429 digits of precision. But remember, that 3.5 bits per decimal digit is only an approximation, not a perfectly accurate answer.

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

值得一提的是,Python在他们的网站上写了以下内容:

Historically, the Python prompt and built-in repr() function would choose the one with 17 significant digits, 0.10000000000000001. Starting with Python 3.1, Python (on most systems) is now able to choose the shortest of these and simply display 0.1.

当格式最终使用定点表示法时,precision()指定小数位数。因为在你的例子中有一个额外的非小数位数,一个比那些可以安全表示的数字还要多。在

当使用科学记数法时,总位数被计算出来,你将得到与原始数字相同的位数(当然还有一个指数)。C和C++选项用于格式化浮点数实际上是相当糟糕的。特别是,没有选项可以让格式化程序决定适当的位数,尽管底层算法实际上可以确定这些位数。在

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

print('{:.16f}'.format(1.305195828773568))
# -> 1.3051958287735681

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

>>> 7205759403792794 * 10**30 // 2**56
100000000000000005551115123125L

In versions prior to Python 2.7 and Python 3.1, Python rounded this value to 17 significant digits, giving ‘0.10000000000000001’. In current versions, Python displays a value based on the shortest decimal fraction that rounds correctly back to the true binary value, resulting simply in ‘0.1’.

“全精度打印”很难做到:什么是全精度?浮点的表示是二进制的;只有2的幂的分数才能精确表示(精确到完全);大多数十进制分数不能以2为基数精确表示。在

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

相关问题 更多 >