浮点数双精度,单精度以及半精度知识总结
最近工作中遇到一个16位半精度浮点数的问题,纠结了很久,特此研究了一下,总结在此:
1.单精度(32位)浮点数的结构:
名称 长度 比特 位置
符号位 Sign(S): 1bit (b31)
指数部分Exponent(E): 8bit (b30-b23)
尾数部分Mantissa(M): 23bit (b22-b0)
其中的指数部分(E)采用的偏置码(biased)的形式来表示正负指数,若E<127则为负的指数,否则为非负的指数。
注意:%f输出float类型,输出6位小数,有效位数一般为7位;
2. 双精度(64位)浮点数的结构
名称 长度 比特位置
符号位 Sign (S) : 1bit (b63)
指数部分Exponent (E) : 11bit (b62-b52)
尾数部分Mantissa (M) : 52bit (b51-b0)
双精度的指数部分(E)采用的偏置码为1023
求值方法:(-1)S*(1.M)*2(E-1023) (公式2)
注意:双精度数也可用%f格式输出,它的有效位一般为16位,给出小数6位。(这一点在计算金额的时候尤为重要,超过有效位的数字是无意义的,一般会出错。
3. 半精度(16位)浮点数结构
名称 长度 比特位置
符号位 Sign (S) : 1bit (b15)
指数部分Exponent (E) : 5bit (b14-b10)
尾数部分Mantissa (M) : 10bit (b9-b0)
最近还诞生了一种Bfloat16的计数方式,使用和半精度相同的位数,实现了保持和单精度一样的指数位也就是8位指数位,可以表示和单精度相同的数字范围,但是牺牲了小数位也就是精度。
半精度浮点数是一种计算机使用的二进制浮点数数据类型。半精度浮点数使用2字节(16位)存储。在IEEE 754-2008中,它被称作binary16。这种类型只适合用来存储那些对精度要求不高的数字,而不适合用来计算。
半精度浮点数是一种相对较新的浮点类型。 英伟达在2002年初发布的Cg语言中将它定义为 half 数据类型,并且首次在2002年末发布的GeForce FX中实现。ILM当时正在寻找一种能够有高动态范围,并且不需要过多消耗硬盘以及内存,而且能像单精度浮点数和双精度浮点数那样被用来进行浮点计算的图像格式。由SGI的John Airey领导的硬件加速可编程着色小组在1997年发明了作为’bali’设计工作的一部分的s10e5数据类型。这曾在SIGGRAPH2000年的论文中介绍过。(见章节 4.3)并且在美国专利7518615中被进一步记录。
半精度浮点数可以在包括OpenEXR,JPEG XR,OpenGL,Cg语言和D3DX等数种计算机图形环境中使用。与8位或16位整数的相比,它的优点是可以提升动态范围,从而使高对比度图片中更多细节得以保留。与单精度浮点数相比,它的优点是只需要一半的存储空间和带宽(但是会以精度和数值范围为代价)
半精度浮点数详解:
IEEE754-2008包含一种“半精度”格式,只有16位宽。故它又被称之为binary16,这种类型的浮点数只适合用于存储那些对精度要求不高的数字,不适合用于进行计算。与单精度浮点数相比,它的优点是只需要一半的存储空间和带宽,但是缺点是精度较低。
半精度的格式与单精度的格式类似,最左边的一位仍是符号位,指数有5位宽且以余-16(excess-16)的形式存储,尾数有10位宽,但具有隐含1。
如图所示,sign为符号位,0表示这个浮点数为正,1表示这个浮点数为负
先介绍尾数,再说指数,fraction为尾数,有10位长,但是有隐含1,尾数可以理解为是一个浮点数小数点后的数,如1.11,尾数就为1100000000(1),最后的隐含1主要用于计算时,隐含1可能存在可以进位的情况。
exponent为指数位,有5位长,具体表示的值有以下几种情况:
当指数位全为0 ,尾数位也全为0的时,表示的就是0
当指数位全为0,尾数位不全为0时,表示为subnormal value,非规格化浮点数,是一个非常小的数
当指数位全为1,尾数位全为0时,表示的是无穷大,此时如果符号位为0,表示正无穷,符号位为1,表示负无穷
当指数位全为1,尾数位不全为0时,表示的不是一个数
其余情况下,指数位的值减去15就是其表示的指数,如11110表示的就是30-15=15
所以我们可以得到,半精度浮点数的值得计算方式为(-1)^sign×2^(指数位的值)×(1+0.尾数位)
备注:这里0.尾数位,表示如尾数位为0001110001,则0.尾数位为0.0001110001
举几个例子:
半精度可以表示的最大值:0 11110 1111111111 计算方法为:(-1)^0×2^(30-15)×1.1111111111 = 1.1111111111×2^15,即十进制的65504
半精度可以表示的最小值(除了subnormal value):0 00001 0000000000 计算方法为:(-1)^(-1)×2(1-15)=2^(-14),约等于十进制的6.104×10^(-5)
再举一个平常的数,这次反过来,如-1.5625×10^(-1) ,即-0.15625 = -0.00101(十进制转二进制)= -1.01×2^(-3),所以符号位为1,指数为-3+15=12,所以指数位为01100,尾数位为0100000000。所以-1.5625×10^(-1)用半精度浮点数表示就为1 01100 0100000000
代码实测:
Float16ToFloat32:
可以把16位的float IEEE754规范的int值转成32位的float
float Float16ToFloat( short fltInt16 )
{int fltInt32 = ((fltInt16 & 0x8000) << 16);fltInt32 |= ((fltInt16 & 0x7fff) << 13) + 0x38000000;float fRet;memcpy( &fRet, &fltInt32, sizeof( float ) );return fRet;}
Float32ToFloat16:
可以把32的float IEEE754规范转化为16位int值
short FloatToFloat16( float value )
{short fltInt16;int fltInt32;memcpy( &fltInt32, &value, sizeof( float ) );fltInt16 = ((fltInt32 & 0x7fffffff) >> 13) - (0x38000000 >> 13);fltInt16 |= ((fltInt32 & 0x80000000) >> 16);return fltInt16;
}
参考链接:
半浮点数详解
浮点数单精度32b与半精度16b转换C语言IEEE 754浮点数单精度32b与半精度16b转换C语言IEEE 754
半精度浮点数和单精度浮点数的转换(不考虑特殊情况)
浮点数双精度,单精度以及半精度知识总结相关推荐
- 单精度和半精度混合训练
单精度和半精度混合训练 概述 混合精度训练方法,通过混合使用单精度和半精度数据格式,加速深度神经网络训练的过程,同时保持了单精度训练所能达到的网络精度.混合精度训练能够加速计算过程,同时减少内存使用和 ...
- 半精度(FP16)调试血泪总结
通常我们训练神经网络模型的时候默认使用的数据类型为单精度(FP32),在该阶段要花费很多的运行时间:而在部署时,为了减少计算量,可以考虑使用16位浮点数,也就是半精度(FP16). 作者丨Allent ...
- 双精度浮点数转换_模型压缩一半,精度几乎无损,TensorFlow推出半精度浮点量化工具包,还有在线Demo...
鱼羊 发自 凹非寺 量子位 报道 | 公众号 QbitAI 近日,TensorFlow模型优化工具包又添一员大将,训练后的半精度浮点量化(float16 quantization)工具. 有了它,就 ...
- 浮点运算/半精度,单精度,双精度/浮点和定点
目录 1.实数数的表示 1.1定点数 1.2浮点数 2.精度说明 2.1半精度FP16 3.浮点运算加法和乘法 3.1加法 3.2乘法 1.实数数的表示 参考深入理解C语言-03-有符号数,定点数,浮 ...
- 在计算机领域,半精度、单精度、双精度的定义,以及多精度计算和混合精度计算的区别。
在计算机系统的内存中,半精度是16bit,单精度是32bit,双精度是64bit. signed bit符号位,有效数字的符号位 Exponent 阶码或者叫指数,以10^Exponent表示 Sig ...
- 单精度 半精度 双精度_单精度与双精度
单精度 半精度 双精度 Here you will learn about Single Precision vs Double Precision. 在这里,您将了解单精度与双精度. When ta ...
- python单精度和双精度的区别_单精度、双精度和半精度浮点格式之间的区别
我们学过数学,都知道有理数和无理数,然后在有理数中有一类叫浮点数的数字,不知道大家对这些还有没有印象? 在软件编程的时候,我们也会用到浮点数,一种既包含小数又包含整数的数据类型. 下面就来讲讲关于浮点 ...
- 单精度、双精度和半精度浮点格式之间的区别
源自公众号strongerHuang 单精度.双精度和半精度浮点格式之间的区别 IEEE 浮点算术标准是用来衡量计算机上以二进制所表示数字精度的通用约定.在双精度格式中,每个数字占用64位,单精度格式 ...
- 使JavaScript的Uint8Array支持读取、写入Half(半精度浮点数)
简单引用百度百科的说明: 半精度浮点数是一种计算机使用的二进制浮点数数据类型.半精度浮点数使用2字节(16位)存储.在IEEE 754-2008中,它被称作binary16.这种类型只适合用来存储那些 ...
最新文章
- c语言程序设计案例教程(第2版)笔记(三)—变量、结构体
- C# 学习笔记(6) 多态
- Oracle序列使用:建立、删除
- 百练OJ:1017:装箱问题
- 数字经济时代凸显网络安全重要性
- [CQOI2015]任务查询系统(差分+主席树)
- 用汇编的眼光看C++(之算术符重载陷阱)
- 小雷:我的核心定位和远大志向(上次更新2013年11月9日)
- 国外NetDevOps资源工具清单分享
- 开关电源的电感选择和布局布线
- BZOJ4816 数字表格
- 大型网站架构技术方案集锦[转]
- 获取PC 服务器 可用的GPU
- reporting services报表部署错误:运行配置文件中指定的扩展时出现异常。 ---> 超过了最大请求长度。
- matlab如何打开dcm_MatLab 与 visual studio 混合编程环境配置
- Tyvj4071放射性辐射尘题解
- TPC116S8 DAC芯片
- Android集成FFmpeg并实现视频转码
- tcpip Socket编程入门
- 对三点雨流计数法的思考