【发布时间】:2019-04-05 18:02:25
【问题描述】:
我得到了一个包含一些双精度、字符和其他的二进制文件。我必须读取文件并使用其中的双精度数执行数值运算。
要读取文件,我会这样做:
std::ifstream infile("../numbers.bin", std::ios::in | std::ios::binary);
if (!infile.is_open()) {
std::cerr << "Could not open file.";
return 1;
}
while(!infile.eof()) {
long first = 0;
double second = 0;
infile.read((char *) &first, sizeof(first));
infile.read((char *) &second, sizeof(second));
double result = first * second;
std::cout << first << "*" << second << " = " << result << std::endl;
}
但是,我得到了这样的东西(看起来不对):
-4397703785598681083*4.77479e-314 = -2.09981e-295
我拿出一个十六进制编辑器查看文件,看起来保存的双精度只有 4 个字节,而不是我机器上的 8 个字节(我使用的是 Linux,二进制文件是在 Windows 机器上构建的。
我的假设是我尝试将一个 4 字节的双精度,在十六进制中看起来像这样:642a 0940 放入一个 8 字节的双精度,这会导致这样的结果:642a 0940 0000 0000 存储到内存中,从而导致错误的双重表示。
所以,我的实际问题是:有没有办法将这个 4 字节双精度以正确的方式放入 8 字节双精度?我认为应该可以在前面加上0s 前缀。
我也知道我可以更改编译器的设置,让双精度数只有 4 个字节而不是 8 个字节,或者我可以只使用浮点数而不是双精度数。 这更多是出于好奇,想了解它是如何工作的,以及为什么在这种情况下它不起作用。
编辑:我尝试使用 float 而不是 double,但它不起作用。结果是-4397703785598681083*2.14321 = -9.42521e+18
【问题讨论】:
-
一个“4 字节双精度”被称为浮点数。
-
为什么不读成
float,然后转换成double(如果需要)? -
为什么是
long?实际的文件格式是什么?它是如何保存的? -
@user207421 格式是
.bin,它是使用不同的 c++ 程序创建的。 -
你有很多黑客行为要做。 C 和 C++ 对二进制文件的唯一保证是您可以读取由同一程序写入的数据。当你处理两个不同的程序时,你必须有一个通用的数据协议;也就是说,您必须知道文件中数据的确切格式才能读取它。称它为
float或double只是一个开始,但它并没有告诉你需要知道的细节。