C语言 如何以人类可读的形式将双精度写入文件并读回确切的双精度?



是否可以以人类可读的形式将任意双精度写入文件,并在读回文件时准确地获得所有 64 位相同的双精度?

当然,这可以通过将双精度值写入二进制数据来实现,例如:

static void writedouble(FILE *fp, double d) {
fwrite(&d, sizeof(double), 1, fp);
}

但这不是我想要的。我希望double以人类可读的形式编写,例如:

static void writedouble(FILE *fp, double d) {
fprintf(fp, "%.14g", d);
}

然后再读一遍,像这样:

static void readdouble(FILE *fp, double *d) {
fscanf(fp, "%.14g", d);
}

之后,我想测试两个double是否相同,例如:

printf("Check: %dn", memcmp(&in_double, &out_double, sizeof(double));

这是否可能,或者只有在将其存储为二进制数据时才能获得位精确的double

是否有可能以人类可读的形式将任意双精度写入文件,并在读回文件时准确地获得所有 64 位相同的双精度?

是的,当然是,只要您使用足够的精度。double最多具有DBL_DECIMAL_DIG位十进制数字的精度,如float.h中所定义,因此以下程序工作正常:

#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <math.h>
#include <float.h>
static void writedouble(FILE *fp, double d) {
fprintf(fp, "%.*g", DBL_DECIMAL_DIG, d);
}
static void readdouble(FILE *fp, double *d) {
fscanf(fp, "%lg", d);
}
int main(void) {
FILE *fp = fopen("test.txt", "w+");
double x = M_PI; // Use pi, just as a test.
double y;
writedouble(fp, x);
rewind(fp);
readdouble(fp, &y);
fclose(fp);
// Check if the actual representation of the two values
// in memory is exactly the same.
assert(memcmp(&x, &y, sizeof(double)) == 0);
return 0;
}

上述内容与您的代码之间的主要区别在于:

  1. 调用printf的精度为DBL_DECIMAL_DIG(17(,而不是14
  2. 调用scanf时没有精度修饰符(因为它不需要也不支持(,而是使用l修饰符,因为(与printf不同(scanf区分float(feg(和double(lflelg(。

另一种可能性是printfscanf%a格式。 它是文本和 100% 可逆的,尽管它在人类可读性部门有些影响。

最新更新