关于float和double在计算机中的存储结构这里就不赘述了,一般主要是PC机法,用补码的方式存储,
不过这个跟我们用程序读取数据的关系不大,计算机自己知道怎么读。
由于Intel系列的CPU都采用小端序标准,即主机字节序与网络字节序相反,所以需要换一下顺序。
float read_float(istream& is)
{
unsigned int value;
is.read((char*)&value, 4);
unsigned int idata1, idata2, idata3, idata4;
idata1 = 255 & (value >> 24);
idata2 = 255 & (value >> 16);
idata3 = 255 & (value >> 8);
idata4 = 255 & value;
char str[9];
sprintf(str, "%02x%02x%02x%02x", idata4, idata3, idata2, idata1);
str[8] = 0;
float a;
sscanf(str, "%x", &a);
return a;
}
这是通过移位的方式来达到最终的目的,也可以直接读到一个字符串里,再变换顺序输出
char re[5];
re[4] = 0;
is.read(re, 4);
for (int i = 0; i < 2; i++)
{
char c = re[i];
re[i] = re[3 - i];
re[3 - i] = c;
}
float a = *(float*)re;
return a;
后面这种方法同样适用于double类型的数据读取,只不过4个字节变8个字节而已。
但是第一种方法用来读取double读到的会是一个错误的结果,至于原因,我想是因为...
unsigned __int64 value;
is.read((char*)&value, 8);
unsigned __int8 idata1, idata2, idata3, idata4, idata5, idata6, idata7, idata8;
idata1 = 255 & (value >> 56);
idata2 = 255 & (value >> 48);
idata3 = 255 & (value >> 40);
idata4 = 255 & (value >> 32);
idata5 = 255 & (value >> 24);
idata6 = 255 & (value >> 16);
idata7 = 255 & (value >> 8);
idata8 = 255 & value;
char str[17];
str[16] = 0;
sprintf(str, "%02x%02x%02x%02x%02x%02x%02x%02x", idata8, idata7, idata6, idata5,idata4, idata3, idata2, idata1);
double a;
sscanf(str, "%x", &a);
这里的字符串str有16个字节,目前C/C++里好像还没有16个字节的数据类型,我猜测可能是从16字节的字符串输出 到8个字节的数据的时候会出问题。
double read_double(istream& is)
{
unsigned __int64 value;
is.read((char*)&value, 8);
unsigned __int64 idata1, idata2, idata3, idata4, idata5, idata6, idata7, idata8;
idata1 = 255 & (value >> 56);
idata2 = 255 & (value >> 48);
idata3 = 255 & (value >> 40);
idata4 = 255 & (value >> 32);
idata5 = 255 & (value >> 24);
idata6 = 255 & (value >> 16);
idata7 = 255 & (value >> 8);
idata8 = 255 & value;
value = (idata8 << 56) + (idata7 << 48) + (idata6 << 40) + (idata5 << 32)
+ (idata4 << 24) + (idata3 << 16) + (idata2 << 8) + idata1;
char str[9];
str[8] = 0;
double a;
memcpy(str, &value, 8);
memcpy(&a, str, 8);
return a;
}
可以改成这样,把变换顺序的数据从新读回value,然后用memcpy来传送数据,
memcpy可以确保字节数为8个字节。
要注意的是,由于
value = (idata8 << 56) + (idata7 << 48) + (idata6 << 40) + (idata5 << 32) + (idata4 << 24) + (idata3 << 16) + (idata2 << 8) + idata1;
这一步要从新移位回去,所以idata1到idata8的类型要由__int8改为__int64,才能进行正确的移位。