在ModelBus协议中,每一个数据使用两个字节来表示,可是float浮点数有四个字节,如何把float转换成两个字节的字节流呢?本文参照IEEE754浮点数标准,给出了一个16位的float定义方法,即符号位1位,阶码位5位,尾数位10位,当然这样做,会损失精度,十进制有效位数只有4位。
#include<iostream> using namespace std; void FloatToBuf(float num, unsigned char buf[2]); float BufToFloat(unsigned char buf[2]); int main() { float f = 639.5f; //待转换的浮点数 int *p = reinterpret_cast<int *>(&f); for(int i = 31; i >= 0; i--) //原始的二进制位 { cout << (*p >> i & 1); if(i % 8 == 0) { cout << ' '; } } cout << endl; unsigned char buf[2]; FloatToBuf(f, buf); for(i = 0; i < 16; i++) //转换后的大端模式二进制位 { cout << (buf[i / 8] >> (7 - i % 8) & 1); if(i % 8 == 7) { cout << ' '; } } cout << endl; cout << BufToFloat(buf) << endl; //再转回去的浮点数 return 0; } float BufToFloat(unsigned char buf[2]) { float sum = 1.0f, item = 0.5f; int index = 0, base = 1, i; for(i = 6; i < 16; i++, item /= 2.0f) { if(buf[i / 8] >> (7 - i % 8) & 1) { sum += item; } } for(i = 5; i > 0; i--, base *= 2) { if(buf[i / 8] >> (7 - i % 8) & 1) { index += base; } } if(index > 0) { index -= 15; if(index > 0) { while(index--) { sum *= 2.0f; } } else { index *= -1; while(index--) { sum /= 2.0f; } } } else { sum -= 1.0f; } if(buf[0] >> 7 & 1) { sum *= -1.0f; } return sum; } void FloatToBuf(float num, unsigned char buf[2]) { float item = 0.5f; int index = 0, i; if(num == 0.0f) { buf[0] = buf[1] = 0; return; } if(num > 0.0f) { buf[0] &= ~(1 << 7); } else { buf[0] |= (1 << 7); num *= -1.0f; } while(num >= 2.0f) { index++; num /= 2.0f; } num -= 1.0f; for(i = 6; i < 16; i++, item /= 2.0f) { if(num >= item) { buf[i / 8] |= (1 << (7 - i % 8)); num -= item; } else { buf[i / 8] &= ~(1 << (7 - i % 8)); } } if(num >= item) { for(i = 15; i > 5; i--) { if(buf[i / 8] >> (7 - i % 8) & 1) { buf[i / 8] &= ~(1 << (7 - i % 8)); } else { buf[i / 8] |= (1 << (7 - i % 8)); break; } } if(i == 5) { index++; } } index += 15; for(i = 5; i > 0; i--) { if(index >> (5 - i) & 1) { buf[i / 8] |= (1 << (7 - i % 8)); } else { buf[i / 8] &= ~(1 << (7 - i % 8)); } } }