C++ 用c+打印30位双精度值+;

C++ 用c+打印30位双精度值+;,c++,floating-point,precision,C++,Floating Point,Precision,我的理解是,numeric_limits::max_digits10给出了小数点后可用的最大位数。但是,如果我将precision()设置为大于此值的值,它仍然会给出超出此最大值的非零位数: assert(std::numeric_limits<double>::max_digits10 == 17); std::cout << std::setprecision(30) << double(.1) << '\n'; 超过17位的数字是否准确?将

我的理解是,numeric_limits::max_digits10给出了小数点后可用的最大位数。但是,如果我将precision()设置为大于此值的值,它仍然会给出超出此最大值的非零位数:

assert(std::numeric_limits<double>::max_digits10 == 17);
std::cout << std::setprecision(30) << double(.1) << '\n';
超过17位的数字是否准确?

将双精度的53位(前导1隐含)尾数转换为二进制定点:

0.00011001100110011001100110011001100110011001100110011010
这等于十进制值

0.1000000000000000055511151231257827021181583404541015625
将问题的结果匹配到30位

0.100000000000000005551115123126

然而,第五十四位可能是未知的,如果你认为这是一个可能的值范围,那么在下面和以上的二进制定点数将是

0.000110011001100110011001100110011001100110011001100110001
0.000110011001100110011001100110011001100110011001100110101
表示十进制值:

0.099999999999999984734433411404097569175064563751220703125
0.100000000000000012490009027033011079765856266021728515625

这意味着16或17位精度。因此,如果你认为双精度数是一个精确的表示而不是最接近的表示,那么精度的30个数字才是准确的。

所需的读数:double被定义为1.7e+/- 308(15位),因此,对于一些数字,你可以上升到308位。但请先阅读@ThomasMatthews的建议。
double
的精度并不是像±10^(-17)一样固定的,它取决于数字的值。数值越大,准确度越差,数值越小越好。换言之,值的±误差是相对于该值确定的。如您所见,数字x的误差约为±0.00000000000000005*xA,关于浮点的信息太多:“非零数字”与有意义的数字不同。存储在变量中的浮点“数字”根本不是十进制数字:它们是二进制数字;而且,也不能保证将二进制转换为十进制的过程只会在没有可用信息时才给你零。
0.099999999999999984734433411404097569175064563751220703125
0.100000000000000012490009027033011079765856266021728515625