在 C++ 中,我可以以文本格式写入和读回浮点型(或双精度型)而不丢失精度吗?
考虑以下因素:
float f = ...;
{
std::ofstream fout("file.txt");
// Set some flags on fout
fout << f;
}
float f_read;
{
std::ifstream fin("file.txt");
fin >> f;
}
if (f != f_read) {
std::cout << "precision lost" << std::endl;
}
我理解为什么有时会失去精度。但是,如果我用足够的数字打印该值,我应该能够读回完全相同的值。
是否有一组给定的标志可以保证永远不会丢失精度? 这种行为可以跨平台移植吗?
如果您不需要支持缺乏 C99 支持 (MSVC) 的平台,那么最好的选择实际上是使用
%a
格式说明符和 printf
,它总是生成数字的精确(十六进制)表示,而使用有限数量的数字。如果使用此方法,则在转换为字符串或返回字符串期间不会发生舍入,因此舍入模式对结果没有影响。
查看这篇文章:如何准确打印浮点数,还有那篇文章:快速准确地打印浮点数。
如果我用足够的数字打印该值,我应该能够读回完全相同的值
如果用十进制书写则不然 - 二进制位数和表示数字所需的十进制位数之间不存在整数关系。如果您以二进制或十六进制打印您的数字,您将能够读回它而不会丢失任何精度。
一般来说,浮点数首先不可在平台之间移植,因此您的文本表示无法弥补这一差距。实际上,大多数机器都使用 IEEE 754 浮点数,因此它可能会工作得相当好。
您不一定能以十进制形式打印“二的幂”浮点数的精确值。
考虑使用基数 3 来存储 1/3,现在尝试完美地以十进制打印 1/3。
有关解决方案,请参阅:如何打印浮点数的精确值?