繁体   English   中英

将 IEEE-754 16 位浮点数打包为 16 位无符号 integer,同时保留顺序

[英]Packing an IEEE-754 16-bit float to a 16-bit unsigned integer while preserving order

我有一个 IEEE-754 16 位浮点数,我想将其无损打包为 16 位无符号 integer。最简单的方法当然是打包它的字节然后解包,但问题是我需要之后比较我程序中的 16 位整数(即大于、小于等)。 所以我正在寻找 f16 和 u16 之间保持顺序的同构。 任何人都可以建议执行此操作的算法吗? 谢谢!

要维护具有 integer 数学运算的 float16 的<, ==, > ,请将数据视为使用符号幅度编码的带符号integer 编码。

使用float(u)int32_t执行此操作以使代码正确(因为float16_t并非对所有人都可用),然后针对 16 位进行调整。

将负值取反为正值并将 MSBit 设置为正值。

确保 +0.0 和 -0.0 转换为相同的值。

// Assumes same endian for FP and integers
#include <float.h>
#include <limits.h>
#include <stdint.h>
#include <stdio.h>

// Assumes same endian for FP and integers
unsigned float_to_sequence(float f) {
  union {
    float f;
    int32_t i;
    uint32_t u;
  } x = {.f = f};
  if (x.i < 0) {
    x.u = -x.u;
  } else {
    x.u |= 0x80000000;
  }
  return x.u;
}

测试

void test(float f) {
  printf("%+-20a %+-18.9e ", f, f);
  printf("0x%08X\n", float_to_sequence(f));
}

int main(void) {
  float f[] = {-INFINITY, -FLT_MAX, -1.0, -FLT_TRUE_MIN, -0.0, //
      0.0, FLT_TRUE_MIN, 1.0, FLT_MAX, INFINITY};
  size_t n = sizeof f / sizeof f[0];
  for (size_t i = 0; i < n; i++) {
    test(f[i]);
  }
}

Output

-inf                 -inf               0x00800000
-0x1.fffffep+127     -3.402823466e+38   0x00800001
-0x1p+0              -1.000000000e+00   0x40800000
-0x1p-149            -1.401298464e-45   0x7FFFFFFF
-0x0p+0              -0.000000000e+00   0x80000000
+0x0p+0              +0.000000000e+00   0x80000000
+0x1p-149            +1.401298464e-45   0x80000001
+0x1p+0              +1.000000000e+00   0xBF800000
+0x1.fffffep+127     +3.402823466e+38   0xFF7FFFFF
+inf                 +inf               0xFF800000

转换是一对一的,除了 +0.0 和 -0.0 都转换为相同的值——这是应该的。

对于 16 位单行: uint16_t y = (x & 0x8000)? -x: (x | 0x8000); uint16_t y = (x & 0x8000)? -x: (x | 0x8000);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM