half(fp16)类型转float(fp32)类型的简单实现
half和float的数据格式
half (fp16)
组成:符号位 1 bit + 指数位 5 bits + 小数位 10 bits。
指数位的表示范围是[2^-14, 2^15]。
float (fp32)
组成:符号位 1 bit + 指数位 8 bits + 小数位 23 bits。
指数位的表示范围是[2^-126, 2^127]。
算法原理
只要half类型的值不是nan,则转换为float后,符号位不变。
特殊值处理
当half类型的绝对值为0.0 (0x0000)时
转化为float后绝对值依然为0.0 (0x00000000)。
当half类型的绝对值为INF (0x7C00)时
转化为float后绝对值为INF (0x7F800000)。
当half类型的绝对值大于INF (0x7C00)时
此时数值为NAN,转化为float后统一为NAN (0x7FC00000)。
其他情况
当half类型的指数位值不为0时
指数位转换:当表示的指数为2^0=1时,half类型的指数位为0x10,float类型指数位为0x80。因此在half转float后,指数位需要加0x70。
小数位转换:由于half类型的小数位长度是 10 bits,float类型的小数位长度为 23 bits。因此在half转float后,小数位需要左移 13 bits。
当half类型的指数位值为0时
注意,当浮点数的指数位为0时,小数位表示的数值是 0.xxxxx,而当指数位不为0时,小数位表示的数值位 1.xxxxx。
由于half类型指数位最小(0x0)能表示的是2^-14,因此转化为float后指数位必然不为0。
因此小数位除了要左移13位之外,还需要继续左移至最高为的1省略掉,同时指数位也要减去 (额外的左移值 - 1)。
指数位转换:half转float后,指数位需要加0x70,再减去 (额外的左移值 - 1)。如图所示,当half转换为float时,小数位共左移了 (13 + 4) bits,因此float类型的指数位值为 0 + 0x70 - (4 - 1) = 0x6D。
小数位转换:首先要确认half类型数值小数位的最高位1的位置,在转换为float后,需要左移直至该最高位的1被省去。如图所示,half小数位最高位的1位于第7 bit位,因此小数位需要左移 (13 + (10 - 6)) = (13 + 4) bits。
示例代码
float f16_to_f32(half __x) {unsigned short n = *((unsigned short *)&__x);unsigned int x = (unsigned int)n;x = x & 0xffff;unsigned int sign = x & 0x8000; //符号位unsigned int exponent_f16 = (x & 0x7c00) >> 10; //half指数位unsigned int mantissa_f16 = x & 0x03ff; //half小数位unsigned int y = sign << 16;unsigned int exponent_f32; //float指数位unsigned int mantissa_f32; //float小数位unsigned int first_1_pos = 0; //(half小数位)最高位1的位置unsigned int mask;unsigned int hx;hx = x & 0x7fff;if (hx == 0) {return *((float *)&y);}if (hx == 0x7c00) {y |= 0x7f800000;return *((float *)&y);}if (hx > 0x7c00) {y = 0x7fc00000;return *((float *)&y);}exponent_f32 = 0x70 + exponent_f16;mantissa_f32 = mantissa_f16 << 13;for (first_1_pos = 0; first_1_pos < 10; first_1_pos++) {if ((mantissa_f16 >> (first_1_pos + 1)) == 0) {break;}}if (exponent_f16 == 0) {mask = (1 << 23) - 1;exponent_f32 = exponent_f32 - (10 - first_1_pos) + 1;mantissa_f32 = mantissa_f32 << (10 - first_1_pos);mantissa_f32 = mantissa_f32 & mask;}y = y | (exponent_f32 << 23) | mantissa_f32;return *((float *)&y);
}
推荐:float-toy
half(fp16)类型转float(fp32)类型的简单实现相关推荐
- 转载——C语言中float,double类型,在内存中的结构(存储方式)
最近在做一个数据格式分析和转换的项目,第一次接触底层的二进制代码存储,看的一头雾水,看到这个帖子后对于在Windows系统下数据的存储方式有了更多的了解,将原文分享一下: 原文地址为http://ww ...
- matlab中float类型的_Java局部变量类型推断(Var类型)的26条细则
原文链接:https://dzone.com/articles/var-work-in-progress 作者:Anghel Leonard 译者:沈歌 Java局部变量类型推断(LVTI),简称 v ...
- android 字符串转浮点,Android String类型转换为float、double和int的工具类方法
在做项目时遇到了需要把年份(String)转换为int类型,对年份进行比较,顺便提取为方法,保存下来方便以后使用. public class ConvertUtil { //把String转化为flo ...
- C# string类型转换为float精度问题
C# string类型转换为float精度问题 使用float scoValue = float.Parse(scorestr); 的方法,在提交小数的时候会出现精度丢失问题, 如果是0.5则没有问题 ...
- mysql:列类型之float、double
环境: window10 vs2022 .net 6 mysql 8.0.25 DBeaver 参考: <MSDN:浮点数值类型(C# 引用)> <mysql:11.1.4 Floa ...
- android 字符转double,Android String类型转换为float、double和int的工具类方法
在做项目时遇到了需要把年份(String)转换为int类型,对年份进行比较,顺便提取为方法,保存下来方便以后使用. public class ConvertUtil { //把String转化为flo ...
- 2.1_3 Oracle float number类型 详解 + 测试实例(测试小数发现BUG)
目录 前言 1 定义 1.1 FLOAT 类型 1.2 NUMBER 类型 2 测试实例 2.1 测试环境 2.2 DDL测试表 SQL 2.3 查看表结构 SQL 2.4 插入测试值 2.5 分类讨 ...
- 设变量n为float类型,m为int类型,则以下能实现将n中的数值保留小数点后两位,第三位进行四舍五人运算的表达式是: A) n=(n*100+0.5)/100.0 B)m=n*100+0.5
设变量n为float类型,m为int类型,则以下能实现将n中的数值保留小数点后两位,第三位进行四舍五人运算的表达式是: A) n=(n100+0.5)/100.0 B)m=n100+0.5 ,n= m ...
- 浮点类型(float和double)
浮点类型表示有小数部分的数字.Java语言中浮点类型分为单精度浮点类型(float)和双精度浮点类型(double),它们具有不同的取值范围.如表: 数据类型 内存空间(8位等于1字节) 取值范围 f ...
最新文章
- java 登录按钮响应数据库_用户登录功能的实现—从前端到后台(包括数据库)...
- ES6入门概览二--数组
- Linux CentOS 7【修改 屏幕(分辨率)大小】
- HDU 2444:The Accomodation of Students(二分图判定+匹配)
- 中国.NET:东莞+长沙.NET俱乐部现场花絮及合肥、苏州、上海等地活动预
- 不只是舒适,简直是享受,Google公司用的腰靠,到底有什么秘密?
- OpenCV示例学习(二): 基本图形绘制算子:line(),circle(),fillPoly(), ellipse()
- Linux进程学习(孤儿进程和守护进程)
- 怎么提升企业数据分析能力
- C++RAII惯用法:C++资源管理的利器
- 如何在一台电脑上使用两个git@osc的账号进行操作
- 0-1背包问题(回溯算法)
- @Autowired注解位置、@Autowired与@Resource的区别与注入流程
- WooCommerce税收入门指南,第2部分
- vscode利用ssh远程连接linux虚拟机
- 计算机桌面文件删除不掉是怎么了,电脑删除不了文件怎么办?教你几种好的处理方法,一学就会...
- Spring Boot编程思想 核心篇 小马哥
- QQ发送网址链接 安全性未知
- 2021/04/10 OJ每日一题 1190: 按出生日期排序(结构体专题)python
- 【中秋系列】这款秘制Python月饼游戏,拿走不谢~