用C+编写一个全精度浮点+; 在C++中,我可以写和读一个浮点(或双)文本格式而不丢失精度吗?

用C+编写一个全精度浮点+; 在C++中,我可以写和读一个浮点(或双)文本格式而不丢失精度吗?,c++,io,floating-point,C++,Io,Floating Point,考虑以下几点: 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

考虑以下几点:

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;
  }
float f=。。。;
{
std::of stream fout(“file.txt”);
//在fout上设置一些标志
fout>f;
}
如果(f!=f_读取){
标准::cout
如果我用足够的数字打印值,我应该能够读回完全相同的值

如果你用十进制写的话就不需要了——二进制数字的数量和表示一个数字所需的十进制数字的数量之间没有整数关系。如果你用二进制或十六进制打印出数字,你就可以在不损失任何精度的情况下读回它


一般来说,浮点数首先不能在平台之间移植,因此您的文本表示无法弥补这一差距。实际上,大多数机器使用IEEE 754浮点数,因此它可能工作得相当好。

您不必打印“二的幂”的确切值十进制浮点数。
考虑使用基数3来存储1/3,现在尝试以十进制打印1/3


有关解决方案,请参阅:

看看这篇文章:还有那篇:


stackoverflow中也提到了它,并且有一些指向实现的指针。

如果您不需要支持缺乏C99支持(MSVC)的平台,那么最好的选择实际上是将
%a
格式说明符与
printf
一起使用,它总是生成精确的(十六进制)使用有界位数表示数字。如果使用此方法,则在转换为字符串或返回期间不会发生舍入,因此舍入模式对结果没有影响。

如果我有足够的十进制数字,则应该有一个最接近表示的单浮点数,否?@luis,不一定-可能例如,您无法控制舍入行为,因此,如果您打印一个十进制数,它以一种方式舍入,然后在读回时以另一种方式舍入,您将被卡住。这就是我的问题:是否可以设置舍入,使其以简单的方式工作?@luis-100%编译器和系统相关。您将阅读您的文档。它肯定是不可移植的。如果您想要精确存储和加载,请将浮点的二进制表示形式转换为base64并存储它……”但是,如果我用足够的数字打印值,我应该能够读回完全相同的值是的,大约有17位有效的十进制数字。相关的C问题:。这是错误的。因为10是2的倍数,所以每个浮点数都有一个十进制的有限表示(反之则不正确)@Stephen-你说得对,显然IEEE754要求,如果你使用正确的小数位数,舍入规则必须生成正确的结果浮点。尽管如果你打印更多,它们不会生成正确的结果浮点。我实际上是指纯数学意义上的舍入规则。这种情况与用十进制写1/3完全不同,因为3不除法de 10均匀。忽略IEEE754,每个二元有理数都可以用有限个十进制数字来书写。@Stephen-是的,这是一个糟糕的例子,我混淆了解释,你不一定能在一个基数中有限地表示另一个基数中的分数-但当然你可以在基数2和10中表示(除了格式中的roundign规则)如果文件中不需要人工读取,则只需将数字打印为十六进制
printf(“%8X%16X”,1.1f,1.1);
。这是最快的,无论C99如何都可以使用support@LưuVĩnhPhúc:两件事:
%a
是人类可读的,而您的建议会调用未定义的行为(特别是,它不会在大多数64位平台上执行您想要的操作;它只会打印任意垃圾位)。该行为不是未定义的,因为printf只是从堆栈中弹出8个字节,并根据格式化程序决定该数据类型。如果使用%a,它会将这些字节视为双字节,%lld会将它们视为long long int,类似地,%llX会将它们打印为十六进制。我上面键入的代码有一些错误。正确的应该是
printf(“%08llX%016llX”,1.1f,1.1);
另一种使用方法是
printf(“%08X\n”,*(int*)&a);
这就是printf在一些平台上的工作方式。但是,没有什么可以保证。在64位osx或Linux上试用,看看会发生什么…@LưuVĩnhPhúc“只是从堆栈中弹出8个字节,然后决定数据是什么”-->FP值有时会在FP堆栈中传递,而整数有时会在普通堆栈中传递。
printf(“%8X%16X”,1.1f,1.1);