是否有流操纵器的组合(或标准C ++中的任何其他方法),可以让我在C ++中打印double
时获得“正确的”数字?
“正确的”数字是指here所定义的位数:
m或a的小数部分必须打印多少个数字?必须至少有一个数字来表示小数部分,并且除此以外,还需要与唯一的双精度类型的值唯一地区分参数值的数字一样多,但也只有尽可能多的数字。也就是说,假设x是由该方法针对有限的非零参数d生成的十进制表示形式表示的精确数学值。则d必须是最接近x的double值;或者,如果两个double值均等近于x,则d必须是其中之一,并且d的有效位的最低有效位必须为0。
在一个简单的示例中,让我们假设我们有三个double
值:DD,D0和D1。 DD是“中间”,D1的尾数大1,D0的小1。
当以非常大的任意精度打印时,它们会产生以下值(示例中的数字完全无效):
D0 => 1.299999999701323987
DD => 1.300000000124034353
D1 => 1.300000000524034353
(EPSILON,0指数尾数的最低有效位的值为〜0.0000000004)
在这种情况下,上面的方法将产生
D0 => 1.2999999997
DD => 1.3
DD => 1.3000000005
答案 0 :(得分:4)
如果我对您的理解正确,那么您想要std::to_chars
。
在默认(“ C”)语言环境中,value会被
std::printf
转换为字符串。转换说明符是f
或e
(在出现平局的情况下优先使用f
),它是根据最短表示的要求选择的:字符串表示由最小的数字组成字符,以使小数点(如果存在)之前至少有一个数字,并使用相应的std::from_char
s函数解析表示形式即可准确恢复值。如果存在多个这样的表示形式,则选择与值的差异最小的一种表示形式,并根据std::round_to_nearest
使用舍入来解决所有剩余的平局。
这是一个低级功能,因此打印结果需要做一些工作:
#include <charconv>
#include <iostream>
int main()
{
double val = 0.1234;
char buf[64];
std::to_chars(buf, buf + sizeof buf, val).ptr = '\0';
std::cout << buf << '\n';
}
遗憾的是,MSVC似乎是目前唯一支持少precision
的重载的编译器。
答案 1 :(得分:0)
缺少尚未实现的C++17 library function,您可以尝试精度(等于%g
的精度),直到精确到四舍五入为止。如果您不在乎非标准数字(甚至两位数字可能太多),请从15开始为IEEE 754加倍;永远不会产生无意义的尾随数字。您再也不必超过17岁了。