用C ++编写完全精确的float

lui*_*dro 5 c++ floating-point io

在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;
  }
Run Code Online (Sandbox Code Playgroud)

我了解为什么有时会丢失精度。但是,如果我用足够的位数打印该值,则应该能够读回完全相同的值。

是否有给定的标志集可以确保永远不会丢失精度?这种行为可以跨平台移植吗?

Lio*_*gan 6

看看这篇文章:How to Print Floating-Point Numbers Accurately and the one:Printing Floating-Point Numbers Quick and Accurately

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


Ste*_*non 6

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


Car*_*rum 5

如果我用足够多的数字打印值,我应该能够读回完全相同的值

如果你用十进制写它就不是 - 二进制数字的数量和代表一个数字所需的十进制数字的数量之间没有整数关系。如果您以二进制或十六进制打印您的数字,您将能够在不丢失任何精度的情况下读取它。

通常,浮点数首先不能在平台之间移植,因此您的文本表示将无法弥合这一差距。在实践中,大多数机器使用 IEEE 754 浮点数,所以它可能会工作得相当好。