float压缩
Published:
本文介绍float 数据的有损压缩。
#include <stdio.h>
#include <cstdint>
/// navi decode
inline void decode(uint32_t packed, float* out) {
union {
uint32_t u32;
uint8_t u8[4];
} buff;
buff.u32 = packed;
#pragma GCC unroll 4
for (int i = 0; i < 4; ++i) {
out[3 - i] = buff.u8[i] / 100.0f;
}
}
inline void decodep50(uint32_t packed, float* out) {
union {
uint32_t u32;
uint16_t u16[2];
} buff;
buff.u32 = packed;
#pragma GCC unroll 2
for (int i = 0; i < 2; ++i) {
out[1 - i] = buff.u16[i] / 1000.0f;
}
}
/// nni encode
inline uint32_t encode(const float* __restrict p) {
return (uint32_t(p[0] * 100) << 24) | (uint32_t(p[1] * 100) << 16) | (uint32_t(p[2] * 100) << 8) |
uint32_t(p[3] * 100);
}
/// nni encode
inline uint32_t encodep50(const float* __restrict p) {
return (uint32_t(p[0] * 1000) << 16) | (uint32_t(p[1] * 1000));
}
int main() {
constexpr int raw_length = 12;
constexpr int ratio = 2;
constexpr int encoded_length = raw_length / ratio;
float raw[raw_length] = {
0.2341f,
0.5632f,
0.1713f,
0.1225f,
0.1126f,
0.8907f,
0.3339f,
0.2547f,
0.7121f,
0.9982f,
0.5333f,
0.9811f,
};
uint32_t packed[encoded_length];
for (int i = 0; i < encoded_length; ++i) {
if (ratio == 4)
packed[i] = encode((float*)raw + i * ratio);
else if (ratio == 2)
packed[i] = encodep50((float*)raw + i * ratio);
}
float out[raw_length];
for (int i = 0; i < encoded_length; ++i) {
if (ratio == 4)
decode(packed[i], (float*)out + i * ratio);
else if (ratio == 2)
decodep50(packed[i], (float*)out + i * ratio);
}
printf("Raw values: ");
for (int i = 0; i < raw_length; ++i) {
printf("%f ", raw[i]);
}
printf("\n");
printf("Decoded values: ");
for (int i = 0; i < raw_length; ++i) {
printf("%.3f ", out[i]);
}
printf("\n");
return 0;
}
// g++ main.cc -o test
