{fmt} 库中精度格式说明符的最大允许值
Maximum allowed value of the precision format specifier in the {fmt} library
考虑以下片段1(可测试here):
#include <fmt/core.h>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
// Let's see how many digits we can print
void test(auto value, char const* fmt_str, auto std_manip, int precision)
{
std::ostringstream oss;
oss << std_manip << std::setprecision(precision) << value;
auto const std_out { oss.str() };
auto const fmt_out { fmt::format(fmt_str, value, precision) };
std::cout << std_out.size() << '\n' << std_out << '\n'
<< fmt_out.size() << '\n' << fmt_out << '\n';
}
int main()
{
auto const precision{ 1074 };
auto const denorm_min{ -0x0.0000000000001p-1022 };
// This is fine
test(denorm_min, "{:.{}g}", std::defaultfloat, precision);
// Here {fmt} stops at 770 chars
test(denorm_min, "{:.{}f}", std::fixed, precision);
}
根据 {fmt}
图书馆的 documentation:
The precision is a decimal number indicating how many digits should be displayed after the decimal point for a floating-point value formatted with 'f'
and 'F'
, or before and after the decimal point for a floating-point value formatted with 'g'
or 'G'
.
这个值有限制吗?
在我发布的极端案例中,std::setprecision
似乎能够输出所有
请求的数字,而 {fmt}
似乎停在 770(在大多数情况下“合理”足够大的值,公平)。有没有我们可以设置的参数来修改这个限制?
编辑
我报告了 issue to the library mantainers and it appears to have been fixed,现在。
(1) 如果您想知道这些特定值的来源,我正在玩这个问答:
What is the maximum length in chars needed to represent any double value?
您离得不远了,format-inl.h
文件 (see here) 中的硬编码限制为 767:
// Limit precision to the maximum possible number of significant digits in
// an IEEE754 double because we don't need to generate zeros.
const int max_double_digits = 767;
if (precision > max_double_digits) precision = max_double_digits;
精度可以是小于最大值 int
的任何值。
您观察到的是在处理固定浮点格式的非常大精度时的一个现已修复的错误:https://github.com/fmtlib/fmt/issues/2616(感谢报告)。
767 不是精度限制,而是 IEEE754 double 可以具有的最大有效数字位数(其余为零):https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/.
考虑以下片段1(可测试here):
#include <fmt/core.h>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
// Let's see how many digits we can print
void test(auto value, char const* fmt_str, auto std_manip, int precision)
{
std::ostringstream oss;
oss << std_manip << std::setprecision(precision) << value;
auto const std_out { oss.str() };
auto const fmt_out { fmt::format(fmt_str, value, precision) };
std::cout << std_out.size() << '\n' << std_out << '\n'
<< fmt_out.size() << '\n' << fmt_out << '\n';
}
int main()
{
auto const precision{ 1074 };
auto const denorm_min{ -0x0.0000000000001p-1022 };
// This is fine
test(denorm_min, "{:.{}g}", std::defaultfloat, precision);
// Here {fmt} stops at 770 chars
test(denorm_min, "{:.{}f}", std::fixed, precision);
}
根据 {fmt}
图书馆的 documentation:
The precision is a decimal number indicating how many digits should be displayed after the decimal point for a floating-point value formatted with
'f'
and'F'
, or before and after the decimal point for a floating-point value formatted with'g'
or'G'
.
这个值有限制吗?
在我发布的极端案例中,std::setprecision
似乎能够输出所有
请求的数字,而 {fmt}
似乎停在 770(在大多数情况下“合理”足够大的值,公平)。有没有我们可以设置的参数来修改这个限制?
编辑
我报告了 issue to the library mantainers and it appears to have been fixed,现在。
(1) 如果您想知道这些特定值的来源,我正在玩这个问答:
What is the maximum length in chars needed to represent any double value?
您离得不远了,format-inl.h
文件 (see here) 中的硬编码限制为 767:
// Limit precision to the maximum possible number of significant digits in
// an IEEE754 double because we don't need to generate zeros.
const int max_double_digits = 767;
if (precision > max_double_digits) precision = max_double_digits;
精度可以是小于最大值 int
的任何值。
您观察到的是在处理固定浮点格式的非常大精度时的一个现已修复的错误:https://github.com/fmtlib/fmt/issues/2616(感谢报告)。
767 不是精度限制,而是 IEEE754 double 可以具有的最大有效数字位数(其余为零):https://www.exploringbinary.com/maximum-number-of-decimal-digits-in-binary-floating-point-numbers/.