double是否有任何流操纵器(或标准 C++ 中的任何其他方法)的组合可以让我在 C++ 中打印时获得“正确”的位数?
我所说的“正确”数字是指此处定义的位数:
m 或 a 的小数部分必须打印多少位数字?必须至少有一位数字来表示小数部分,除此之外,还必须有尽可能多的数字来唯一区分参数值与 double 类型的相邻值。也就是说,假设 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
Run Code Online (Sandbox Code Playgroud)
(EPSILON,0 指数处尾数的最低有效位的值约为 0.0000000004)
在这种情况下,上述方法将产生
D0 => 1.2999999997
DD => 1.3
DD => 1.3000000005
Run Code Online (Sandbox Code Playgroud)
如果我理解正确的话,你想要std::to_chars。
值被转换为字符串,就像
std::printf在默认(“C”)语言环境中一样。转换说明符是fore(在平局的情况下解析为有利于f),根据最短表示的要求进行选择:字符串表示由最少数量的字符组成,使得小数点之前至少有一位数字(如果存在)并使用相应的 s 函数解析表示std::from_char可以准确地恢复值。如果有多个这样的表示,则选择与值差异最小的一个,并根据 进行舍入来解决任何剩余的关系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';
}
Run Code Online (Sandbox Code Playgroud)
此函数需要最新的标准库:GCC (libstdc++) 11 或更高版本,或 Clang (libc++) 14 或更高版本(当前为 trunk)。MSVC 也支持它。