c++ - 在没有 double 类型的 C 编译器上解析 double IEEE 浮点

标签 c++ c casting avr

我正在使用 8 位 AVR 芯片。 64 位 double 没有数据类型( double 只映射到 32 位 float )。但是,我将通过串行接收 64 位 double ,并且需要通过串行输出 64 位 double 。

如何在不强制转换的情况下将 64 位 double 转换为 32 位 float 并再次返回? 32 位和 64 位的格式都将遵循 IEEE 754。当然,我假设转换为 32 位 float 时会损失精度。

对于从 64 位到 32 位 float 的转换,我正在尝试这个:

// Script originally from http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1281990303
float convert(uint8_t *in) {
  union {
    float real;
    uint8_t base[4];
  } u;
  uint16_t expd = ((in[7] & 127) << 4) + ((in[6] & 240) >> 4);
  uint16_t expf = expd ? (expd - 1024) + 128 : 0;
  u.base[3] = (in[7] & 128) + (expf >> 1);
  u.base[2] = ((expf & 1) << 7) + ((in[6] & 15) << 3) + ((in[5] & 0xe0) >> 5);
  u.base[1] = ((in[5] & 0x1f) << 3) + ((in[4] & 0xe0) >> 5);
  u.base[0] = ((in[4] & 0x1f) << 3) + ((in[3] & 0xe0) >> 5);
  return u.real;
}

对于像 1.0 和 2.0 这样的数字,上述方法有效,但是当我将 1.1 作为 64 位 double 值传递进行测试时,输出稍微偏离了一点(字面意思,不是双关语!),尽管这可能是我的测试有问题。见:

// Comparison of bits for a float in Java and the bits for a float in C after
// converted from a 64-bit double. Last bit is different.
// Java code can be found at https://gist.github.com/912636
JAVA FLOAT:        00111111 10001100 11001100 11001101
C CONVERTED FLOAT: 00111111 10001100 11001100 11001100

最佳答案

IEEE 指定 five different rounding modes , 但默认使用的是 Round half to even .所以你有一个形式为 10001100 11001100 11001100 11001100... 的尾数,你必须将它四舍五入到 24 位。从 0(最高有效)开始对位进行编号,第 24 位为 1;但这还不足以告诉您是否将第 23 位向上舍入。如果所有剩余位均为 0,则不会四舍五入,因为位 23 为 0(偶数)。但是剩下的位不是零,所以你在所有情况下都四舍五入。

一些例子:

10001100 11001100 11001100 10000000...(全为零)不会四舍五入,因为第 23 位已经是偶数。

10001100 11001100 11001101 10000000...(全为零)确实向上取整,因为第 23 位是奇数。

10001100 11001100 1100110x 10000000...0001 总是向上取整,因为其余位并非全为零。

10001100 11001100 1100110x 0xxxxxxx... 从不向上取整,因为第 24 位为零。

关于c++ - 在没有 double 类型的 C 编译器上解析 double IEEE 浮点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5614222/

相关文章:

c++ - 我的代码是未定义的行为吗

c - 二维数组是否需要事先知道它在 C 中的大小?

c++ - reinterpret_cast<char*>(p) 或 static_cast<char*>((void*)p)) 用于字节指针差异,哪个更好?

c++ - 构造函数初始化列表: code from the C++ Primer,第16章

c++ - 没有重复的随机数组生成

c++ - 优化 2D 旋转

php检查mysql日期时出错

c++ - Libzip - 从 zip 读取文件内容

c - printf如何处理字符串

c# - 用更好的图案替换铸件