[英]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.