使用 C++ 实现 FP16 转 FP32 算法
1 简介
在当今高性能计算和深度学习领域,半精度浮点数(FP16)因其存储空间小、计算效率高的特点而被广泛应用。然而,在某些场景下,如精度要求较高的科学计算或者需要与 FP32 数据格式兼容的情况,将 FP16 转换为 FP32 就显得尤为重要。本文将介绍一种基于 C++ 实现的 FP16 到 FP32 的转换算法,该算法不仅考虑了数值精度,还优化了计算效率,旨在为开发者提供一个高效、可靠的解决方案。
2 代码实现
FP16 转 FP32 一般用于深度学习量化模型的后处理中,这里可以参考了 Rockchip 提供的类型转换代码
#ifndef _RKNN_APP_TYPE_HALF_H_
#define _RKNN_APP_TYPE_HALF_H_
typedef unsigned short half;
typedef unsigned short ushort;
typedef unsigned int uint;
uint as_uint(const float x) {
return *(uint*)&x;
}
float as_float(const uint x) {
return *(float*)&x;
}
float half_to_float(half x) { // IEEE-754 16-bit floating-point format (without infinity): 1-5-10, exp-15, +-131008.0, +-6.1035156E-5, +-5.9604645E-8, 3.311 digits
// printf("1\n");
const uint e = (x&0x7C00)>>10; // exponent
// printf("2\n");
const uint m = (x&0x03FF)<<13; // mantissa
// printf("3\n");
const uint v = as_uint((float)m)>>23; // evil log2 bit hack to count leading zeros in denormalized format
// printf("4\n");
return as_float((x&0x8000)<<16 | (e!=0)*((e+112)<<23|m) | ((e==0)&(m!=0))*((v-37)<<23|((m<<(150-v))&0x007FE000))); // sign : normalized : denormalized
}
typedef union suf32
{
int i;
unsigned u;
float f;
} suf32;
half float_to_half(float x)
{
suf32 in;
in.f = x;
unsigned sign = in.u & 0x80000000;
in.u ^= sign;
ushort w;
if (in.u >= 0x47800000)
w = (ushort)(in.u > 0x7f800000 ? 0x7e00 : 0x7c00);
else {
if (in.u < 0x38800000) {
in.f += 0.5f;
w = (ushort)(in.u - 0x3f000000);
} else {
unsigned t = in.u + 0xc8000fff;
w = (ushort)((t + ((in.u >> 13) & 1)) >> 13);
}
}
w = (ushort)(w | (sign >> 16));
return w;
}
void float_to_half_array(float *src, half *dst, int size)
{
for (int i = 0; i < size; i++)
{
dst[i] = float_to_half(src[i]);
}
}
void half_to_float_array(half *src, float *dst, int size)
{
for (int i = 0; i < size; i++)
{
dst[i] = half_to_float(src[i]);
}
}
#endif
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构