Java语言在C ++中打印“ double”

时间:2019-01-25 17:37:40

标签: c++ floating-point

是否有流操纵器的组合(或标准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

2 个答案:

答案 0 :(得分:4)

如果我对您的理解正确,那么您想要std::to_chars

  在默认(“ C”)语言环境中,

value会被std::printf转换为字符串。转换说明符是fe(在出现平局的情况下优先使用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岁了。