我目前对此感到惊讶:
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
>>> repr(1.305195828773568)
'1.305195828773568'
发生了什么,为什么C ++中的额外1?
到目前为止,我认为C ++和Python使用相同的64位IEEE双打;两种格式化函数都应该打印出完整的精度。
答案 0 :(得分:10)
你可以强制python打印1(以及更多以下数字):
print('{:.16f}'.format(1.305195828773568))
# -> 1.3051958287735681
来自https://docs.python.org/2/tutorial/floatingpoint.html:
>>> 7205759403792794 * 10**30 // 2**56 100000000000000005551115123125L
在Python 2.7和Python 3.1之前的版本中,Python对此进行了四舍五入 值为17位有效数字,给出'0.10000000000000001'。在 当前版本,Python显示基于最短的值 正确舍入回到真实二进制值的小数部分, 结果只是'0.1'。
&#34;打印全精度&#34;很难做到:全精度是多少?浮点数的表示是二元的;只能得到2的幂的分数(完全精确);大多数小数部分不能在基数2中精确表示。
但是内存中的float对于python和c ++是相同的;它只是字符串表示不同。
答案 1 :(得分:3)
当格式以固定点表示法结束时,precision()
指定小数位数。由于您的示例中还有一个非小数位数,因此创建了一个非安全表示的数字。
使用科学记数法时,会计算总位数,并且您将获得与原始位数相同的位数(当然还有一个指数)。用于格式化浮点数的C和C ++选项实际上相当糟糕。特别是,没有选项可以让格式化程序决定适当的位数,尽管基础算法实际上可以确定这些位数。
答案 2 :(得分:2)
取自this question的回答:
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。