格式化浮动:返回默认值
Formatting floats: returning to default
我 运行 陷入了浮点值的格式化问题,就返回到 "default formatting" 而言。
假设我有 2 个花车:
float f1 = 3.0f, f2 = 1.5f;
std::cout << f1 << " - " << f2 << "\n";
将显示为:3 - 1.5
现在,出于某种原因,我需要在 std::cout
上设置精度(用于其他打印):
cout << std::precision(2);
如果我再次打印我的两个浮点数,这将导致:3.00 - 1.50
现在我想恢复默认格式。在 C++11 之前,这似乎很困难(或者是吗?)。但是,谢谢,我现在有了这个新标志:
std::defaultfloat。让我们试试:
std::cout << std::defaultfloat << f1 << " - " << f2;
将打印:3 - 1.50
。很好。
哦,等等。假设我有:
float f1 = 444.0f, f2 = 444.5f;
默认打印会显示:444 - 444.5
设置精度(和"fixed"):
cout << std::precision(2) << std::fixed;
将显示:444.00 - 444.50
但回到"default":
std::cout << std::defaultfloat << f1 << " - " << f2;
将打印:4.4e+02 - 4.4e+02
(自动切换到科学格式)。而且,如果您想知道,附加 "fixed" 标志将保持先前指定的精度,因此不会返回到原始设置。
问题:如何回到默认模式?
FWIW,live code is here。
Edit: 这个问题已经被标记为一个骗子但是 linked answer 没有提供问题的答案,它只提到如何获得当前的精度.
编辑 2:根据要求,这里是演示问题的完整代码:
int main()
{
float f1 = 444.5f, f2=443.0f;
std::cout << f1 << " - " << f2 << "\n";
std::cout << std::fixed << std::setprecision(2);
std::cout << f1 << " - " << f2 << "\n";
std::cout << std::defaultfloat;
std::cout << f1 << " - " << f2 << "\n";
}
结果:
444.5 - 443
444.50 - 443.00
4.4e+02 - 4.4e+02
std::precision指定cout显示的精度,当你改变格式时它不会改变。
因此,当您设置 std::precision(2) 时,它指定以下所有格式都将应用该精度显示。
fixed 格式应用精度,因为 n 是小数点后的位数。
默认浮点格式应用精度作为要显示的最大总位数。
它不会重置精度值。
供参考:
ios_base::precision
std::defaultfloat
不会重置精度。 (不要问我为什么)。您可以将其重置为默认值,即定义为 6:
std::cout << std::defaultfloat << std::setprecision(6) << f1 << " - " << f2;
或者你可以在操作之前保存整个流状态并在之后恢复它;请参阅 this thread。
在 C++20 中,您可以使用 std::format
,这是一个无状态的 API。特别是,在一个调用中指定精度不会影响另一个调用:
float f1 = 444.0f, f2 = 444.5f;
std::cout << std::format("{} - {}\n", f1, f2);
// Output: 444 - 444.5
std::cout << std::format("{:.2f} - {:.2f}\n", f1, f2);
// Output: 444.00 - 444.50
std::cout << std::format("{} - {}\n", f1, f2);
// Output: 444 - 444.5
std::format
尚未广泛使用,但您可以使用 the {fmt} library,同时 std::format
是基于它的。它还提供了一个 print
功能,结合了格式化和 I/O:
float f1 = 444.0f, f2 = 444.5f;
fmt::print("{} - {}\n", f1, f2);
// Output: 444 - 444.5
fmt::print("{:.2f} - {:.2f}\n", f1, f2);
// Output: 444.00 - 444.50
fmt::print("{} - {}\n", f1, f2);
// Output: 444 - 444.5
免责声明:我是 {fmt} 和 C++20 的作者 std::format
。
您可以简单地在原始 std::ostream
的 std::streambuf
上创建您自己的 std::ostream
,并在这个新的个人 std::ostream
上设置格式。
#include <iostream>
#include <ostream>
#include <iomanip>
float const f1 = 3.0f, f2 = 1.5f;
void proc1() {
std::ostream out(std::cout.rdbuf());
out << "Inside proc1(), floats are printed like: " << std::setprecision(2) << std::fixed << f1 << " and " << f2 << '\n';
}
int main() {
std::cout << "Inside main(), floats are printed like: " << f1 << " and " << f2 << '\n';
proc1();
std::cout << "Back in main(), floats are printed like: " << f1 << " and " << f2 << '\n';
}
此代码将打印:
Inside main(), floats are printed like: 3 and 1.5
Inside proc1(), floats are printed like: 3.00 and 1.50
Back in main(), floats are printed like: 3 and 1.5
你可以在那里试试:http://coliru.stacked-crooked.com/a/4994c3f604b63d67
基于另一个 std::streambuf
创建 std::ostream
是正确的,因为 std::ostream
的析构函数不会触及其分配的 std::streambuf
。参见:https://en.cppreference.com/w/cpp/io/basic_ostream/%7Ebasic_ostream
我 运行 陷入了浮点值的格式化问题,就返回到 "default formatting" 而言。 假设我有 2 个花车:
float f1 = 3.0f, f2 = 1.5f;
std::cout << f1 << " - " << f2 << "\n";
将显示为:3 - 1.5
现在,出于某种原因,我需要在 std::cout
上设置精度(用于其他打印):
cout << std::precision(2);
如果我再次打印我的两个浮点数,这将导致:3.00 - 1.50
现在我想恢复默认格式。在 C++11 之前,这似乎很困难(或者是吗?)。但是,谢谢,我现在有了这个新标志: std::defaultfloat。让我们试试:
std::cout << std::defaultfloat << f1 << " - " << f2;
将打印:3 - 1.50
。很好。
哦,等等。假设我有:
float f1 = 444.0f, f2 = 444.5f;
默认打印会显示:444 - 444.5
设置精度(和"fixed"):
cout << std::precision(2) << std::fixed;
将显示:444.00 - 444.50
但回到"default":
std::cout << std::defaultfloat << f1 << " - " << f2;
将打印:4.4e+02 - 4.4e+02
(自动切换到科学格式)。而且,如果您想知道,附加 "fixed" 标志将保持先前指定的精度,因此不会返回到原始设置。
问题:如何回到默认模式?
FWIW,live code is here。
Edit: 这个问题已经被标记为一个骗子但是 linked answer 没有提供问题的答案,它只提到如何获得当前的精度.
编辑 2:根据要求,这里是演示问题的完整代码:
int main()
{
float f1 = 444.5f, f2=443.0f;
std::cout << f1 << " - " << f2 << "\n";
std::cout << std::fixed << std::setprecision(2);
std::cout << f1 << " - " << f2 << "\n";
std::cout << std::defaultfloat;
std::cout << f1 << " - " << f2 << "\n";
}
结果:
444.5 - 443
444.50 - 443.00
4.4e+02 - 4.4e+02
std::precision指定cout显示的精度,当你改变格式时它不会改变。
因此,当您设置 std::precision(2) 时,它指定以下所有格式都将应用该精度显示。
fixed 格式应用精度,因为 n 是小数点后的位数。 默认浮点格式应用精度作为要显示的最大总位数。
它不会重置精度值。
供参考: ios_base::precision
std::defaultfloat
不会重置精度。 (不要问我为什么)。您可以将其重置为默认值,即定义为 6:
std::cout << std::defaultfloat << std::setprecision(6) << f1 << " - " << f2;
或者你可以在操作之前保存整个流状态并在之后恢复它;请参阅 this thread。
在 C++20 中,您可以使用 std::format
,这是一个无状态的 API。特别是,在一个调用中指定精度不会影响另一个调用:
float f1 = 444.0f, f2 = 444.5f;
std::cout << std::format("{} - {}\n", f1, f2);
// Output: 444 - 444.5
std::cout << std::format("{:.2f} - {:.2f}\n", f1, f2);
// Output: 444.00 - 444.50
std::cout << std::format("{} - {}\n", f1, f2);
// Output: 444 - 444.5
std::format
尚未广泛使用,但您可以使用 the {fmt} library,同时 std::format
是基于它的。它还提供了一个 print
功能,结合了格式化和 I/O:
float f1 = 444.0f, f2 = 444.5f;
fmt::print("{} - {}\n", f1, f2);
// Output: 444 - 444.5
fmt::print("{:.2f} - {:.2f}\n", f1, f2);
// Output: 444.00 - 444.50
fmt::print("{} - {}\n", f1, f2);
// Output: 444 - 444.5
免责声明:我是 {fmt} 和 C++20 的作者 std::format
。
您可以简单地在原始 std::ostream
的 std::streambuf
上创建您自己的 std::ostream
,并在这个新的个人 std::ostream
上设置格式。
#include <iostream>
#include <ostream>
#include <iomanip>
float const f1 = 3.0f, f2 = 1.5f;
void proc1() {
std::ostream out(std::cout.rdbuf());
out << "Inside proc1(), floats are printed like: " << std::setprecision(2) << std::fixed << f1 << " and " << f2 << '\n';
}
int main() {
std::cout << "Inside main(), floats are printed like: " << f1 << " and " << f2 << '\n';
proc1();
std::cout << "Back in main(), floats are printed like: " << f1 << " and " << f2 << '\n';
}
此代码将打印:
Inside main(), floats are printed like: 3 and 1.5
Inside proc1(), floats are printed like: 3.00 and 1.50
Back in main(), floats are printed like: 3 and 1.5
你可以在那里试试:http://coliru.stacked-crooked.com/a/4994c3f604b63d67
基于另一个 std::streambuf
创建 std::ostream
是正确的,因为 std::ostream
的析构函数不会触及其分配的 std::streambuf
。参见:https://en.cppreference.com/w/cpp/io/basic_ostream/%7Ebasic_ostream