整型与字节数组的转换比较简单,但是浮点数与字节数组的转换比较麻烦。网上流传得比较多的方案是利用联合体或者强制转换来搞,从内存中直接获取字节数组:
union {
char bytes[8];
double d;
};
这种搞法虽然简单,但是这不是一个跨平台的方案。编码有大端序(Big Endian)和小端序(Small Endian),不同平台的情况可能不一样。同时,不同的编译器也有可能导致字节数组不同。总之,这种方案不怎么可靠。
比较靠谱的办法是研究一下IEEE 754对于浮点数的规定,把浮点数拆成指数和尾数,根据规定转换成字节数组。
为此,我们需要将指数和尾数转换为二进制。先说指数部分,由于是整数,所以可以通过每次取余数,然后再除以二的方法,反复操作来获得二进制序列,最后逆序排列一下就可以了。再说尾数部分,根据IEEE 754的设定,尾数部分会有一个“隐藏的1”,因此要先把尾数减去1。做完减法之后,我们可以得到一个范围为0到1之间的一个小数。我们将小数每次乘以2,如果结果大于等于1,那么要减去1,同时该二进制位的值就为1。如果结果小于1,那么该二进制位的值为0。
在C#中的BitConverter类可以用于处理这类问题。我自己开发了一个C++版本的BitConverter,里面实现了可以用于将基础类型转换与字节数组互相转换的函数。https://github.com/YanjieHe/BitConverter
通过这个库,可以设定转换过程是遵循大端序还是小端序。由于转换方式是确定的,因此在不同平台下,浮点数转换成的字节数组也是相同的。