IEEE754转换规则
为了转换十六进制到十进制,这里用到了IEEE754规则
组成
IEEE754标准包含一组实数的二进制表示法。它有三部分组成:
- 符号位
- 指数位
- 尾数位
三种精度的浮点数各个部分位数如下:
精度 | 符号 | 阶 | 尾数 | 总位数 |
---|---|---|---|---|
单精度 | 1 | 8 | 23 | 32 |
双精度 | 1 | 11 | 52 | 64 |
长双精度 | 1 | 15 | 64 | 80 |
正规化
对于将某个实数表示为计算机浮点数,首先要将其正规化,也就是表示为形如:
的样子。其中b是0或1,而p二进制数表示的指数位。这样,假设想表示为单精度的浮点数,那么第一位符号位用0表示正,用1表示负,在将指数p加上移码表示为8位的二进制数,在接下来的23位填充位数b部分。由于正规化表示时,最左边部分总是1,所以我们只需表示23位的尾数即可。
移码
上述中有一个词:移码(exponential bias)。因为指数p有正有负,那么在8位的指数位中我们就要拿出第一位来指示符号,这样显然会造成不必要的浪费。给指数加上移码,就能保证结果总是一个非负数,也就可以将8个指数位都利用起来。对于有M个指数位的精度,其移码为:
这样就得到上面三种精度的移码:
精度 | 阶 | 移码 | 二进制表示 |
---|---|---|---|
单精度 | 8 | 127 | 0111 1111 |
双精度 | 11 | 1023 | 011 1111 1111 |
长双精度 | 15 | 16383 | 011 1111 1111 1111 |
以双精度的为例。双精度的指数位有11位。这样可以表示的数是从000 0000 0000
到111 1111 1111
,也就是指数加移码所表示的范围从0到2047,那么,减去移码1023,则可以表示的指数是-1023到1024。但是注意,-1023和1024作为他用(后面会说到)。所以实际上能表示数的指数是从-1022到1023。
栗子
【例】:求3.14的单精度浮点数表示。
首先将3.14转成二进制。整数部分3的二进制是11b,而小数部分0.14的二进制是:0.0010001111010111000010[10001111…]b(方括号中表示小数点后第23位及之后)。这样,3.14的二进制代码就是:11.0010001111010111000010[10001111…]×20,那么用正规化表示就是:1.10010001111010111000010[10001111…]×21。 方括号表示的就是小数点后第24位了,由于单精度浮点数尾数只有23位,所以需要舍入(舍入方法见后):由于第24位为1,且之后不全为0,所以需要向第23位进1完成上舍入:1.10010001111010111000011×21。而其指数是1,需要加上移码127,即128,也就是(000
1000 0000)b。它又是正数,所以符号为0。综上所述,3.14的单精度浮点数表示为: 0 000-1000-0000
1001-0001-1110-1011-1000-011 十六进制代码为:0x4048F5C3
作者:KyrinWoo
链接:https://www.jianshu.com/p/e5d72d764f2f
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
通过此例可知,3.14的单精度浮点数表示是0 000-1000-0000 1001-0001-1110-1011-1000-011
。现在我们来还原,看看它的误差。
指数是128,那么还原回去,实际指数就是1
尾数还原也就是:10010001111010111000011
,所以是:1.10010001111010111000011×21,也就是11.0010001111010111000011。利用二进制转十进制,可得它对应的十进制数是:3.1400001049041748046875。显然与3.14是有误差的。
我们再通过另一种方法估算误差。从例子中可知,对于3.14的单精度浮点数,我们舍去了第24位以及之后,它们是:…[10001111…]×21。不妨假设此后全是0,也就是舍去了0.10001111b×2-23×21约为0.00000013317912817001;而后,由于舍入进位关系,给第23位又加了1,所以加了:2-23×21。所以,误差约为2-23×21-0.10001111b×2-23×21=0.00000010523945093155。所以结果大致为3.14+0.00000010523945093155=3.14000010523945093155。
可见和上面计算结果大致相同。
机器ε(machine epsilon)
机器ε表示1与大于1的最小浮点数之差。不同精度定义的机器ε不同。以双精度为例,双精度表示的1是:
而比1大的最小双精度浮点数是:
可见,此二者之差为:2-52≈2.220446049250313e-16。所以它就是双精度浮点数的机器ε。
在舍入中,相对舍入误差不能大于机器ε的一半。比如上面的3.14的单精度浮点数,二者误差绝对值是0.0000001049041748046875…,从而相对舍入误差为0.0000001049041748046875…÷3.14≈0.00000003340897286773。而单精度浮点数的机器ε为2-23≈1.1920928955078125e-7,它的一半是0.00000005960464477539
。显然,相对舍入误差小于单精度浮点数机器ε的一半。
非正规化:0的表示
从正规化中可知,无论如何浮点数都满足最左边是1。这就有一个严重问题:0没有办法被表示。为此,可以使用非正规化的表示方法,即让最左边默认为0,这样再另尾数也全部为0,就可以表示0了。
新的问题又来了:什么情况下是非正规化,什么情况下又是正规化呢?
答案就是通过指数部分来反映。记得前面说过,双精度浮点数中,指数加移码的范围可以从0到2047,然而0和2047是作为他用的。在这里,指数部分为0就代表着非正规化。所以,当见到指数部分为0时,尾数部分就不再是1.bbbbb…而是0.bbbbb…了。
再进一步,对于非正规化,可以看成是正规化中,小数点向左边跑了一位:1.bbbb…×2-1023=0.1bbbb…×2×2-1023=0.1bbbb…×2-1022(只是概念上理解,小数第一位也不一定非要是1,如0.001010×2-1022也可)。所以,非正规化下表示为:
现在,0就可以表示了。值得注意的是,此时0可以表示位+0和-0。
因为它的最左边不是1是0,实际上可以表示更小的数。双精度浮点数下,使用非正规化可以表示的最小的正数是0.00…01×2-1022也就是2-52×2-1022=2-1074。
请注意这个最小数和前面提到的机器ε的区别。比机器ε小的数是可以被表示出来的(利用非正规化)。但是当它们与其他浮点数做运算时,因为要转成同一种格式(正规化格式),从而可能会因为溢出位而被舍弃。最终结果就是,这些更小的数尽管能被表示,但是对运算结果没有影响。
浮点数加法
机器加法要先将两个操作数的小数点对齐,相加后再转为浮点数存储。这里最重要的一点是,尽管浮点数有位数限制,但是加法会在精度更高的寄存器中进行,这意味着,寄存器能够运算出比52位还要多的位数,但是在转回浮点数存储时,多余位数会被舍弃,造成两者相加的机器结果不严格等于算术结果。
无穷大与NaN
上面说到,在双精度浮点数中,指数为0表示非正规化,那么指数为2047(二进制是111 1111 1111b
,即11位指数位全为1)就表示无穷大和NaN(Not a Number)。具体表现在,当指数是2047,当尾数,全为0就表示无穷大,当尾数不全为0就表示NaN。
舍入规则
以52位尾数位的双精度浮点数为例,舍入时需要重点参考第53位:
若第53位为1,而第53位之后全部为0。此时就要使第52位为0:若第52位本来就是0则不管,若第52位为1,则第53位就要向第52位进一位,这样第52位就可以为0
若不是上面的情况,即第53位1,但是第53位之后不全为0,则第53位就要向第52位进一完成上舍入。
若也不是上面两种情况,那么第53位必为0,此时直接舍去不进位,称为下舍入。
由于存在这种舍入规则,浮点数一般在机器内都不会以原数精确相等的存储,这就会使在某些情况下,使用浮点数做算术运算时出现令人费解的情况,如在JavaScript中(数以双精度存储):
>>9.4-9-0.4===0
<<false
>>(9.4-9-0.4).toFixed(20)
<<"0.00000000000000033307"
可见9.4-9-0.4不严格等于0,其结果有极小误差。因为按照上面的算法可知,9.4在机器内被表示为:9.4+0.2×2-49,而0.4被表示为0.4+0.1×2-52。这样,当9.4-9时(因为9是整数是可以精确存储的)得0.4+0.2×2-49,再减去0.4+0.1×2-52得3×2-53,约等于"0.00000000000000033307"。
循环小数的二进制转回十进制的技巧
某循环小数的二进制码是:0. 0110 0110 0110 0110
0110…b。可见是0110的循环,令x为其十进制数:x=0.01100110…b,则24x=110,01100110…b,两式相减得:(24-1)x=110b,即15x=6,从而x=6/15=0.4
作者:KyrinWoo
链接:https://www.jianshu.com/p/e5d72d764f2f
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
IEEE754转换规则相关推荐
- 基本数据类型转换规则
基本数据类型转换规则 前言 一. byte.short.char运算的规则 二. 多种数据类型混合运算规则 三.总结 前言 在这篇文章中,我对Java的基本类型数据类型的混合运算做了一些总结,希望可以 ...
- IEEE-754标准(32位) 十六进制转换十进制浮点数
因实验需要,读取陀螺仪的数据是16进制的数据,需要将该数据转化为10进制方便自己查看,理解.记录如下: 1.将(32位)16进制IEEE-754标准浮点数就是用十六进制表示浮点,称为单精度浮点数. f ...
- Java虚拟机规范阅读(二)IEEE754简介以及Java虚拟机中的浮点算法
什么是浮点数 在计算机系统的发展过程中,曾经提出过多种方法表达实数.典型的比如相对于浮点数的定点数(Fixed Point Number).在这种表达方式中,小数点固定的位于实数所有数字中间的某个位置 ...
- 从IEEE754标准谈C语言浮点数据类型
先看下面几个问题,如果你能准确地回答,那么此篇文章将不适合你: 计算机中怎样表示浮点数的,与整型的表示方法有什么不同? 32位精度的float类型和64位精度的double类型能表示浮点数最大范围是多 ...
- java:不同数据类型的转换规则
当参数运算的两个变量的数据类型不同,就需要进行隐式的数据类型转换. 转换规则: 优先级满足: byte < short < char < int < long < flo ...
- java32位无符号数_用C语言解释32位无符号长单精度IEEE-754浮点数
我使用的是Microchip的XC32编译器,它基于标准的C编译器 . 我正在从RS485网络上的设备读取32位值并将其存储在unsigned long中,我将其命名为DWORD . 即 typede ...
- Java忽略算术溢出,IEEE-754:“最小”溢出条件
Before I start, just some background information: 我正在使用编译器标准数学库(符合IEEE-754)在Keil uVision3中编译的ARM7微控制 ...
- 进制转换Visual Basic—进制转换规则
进制转换规则 @ Mayuko 转载于:https://www.cnblogs.com/mayuko/p/4567580.html
- 前缀、中缀和后缀表达式详解,中缀表达式到后缀表达式的转换规则,以及后缀表达式的计算规则,附计算代码
1. 中缀.前缀和后缀表达式 1.1 中缀表达式 首先,中缀表达式的这个"缀"指运算符在两个操作数的位置.中缀表达式其实就是我们常用的算术表达式,比如 2 + 9 - (32 * ...
最新文章
- go linux 源码编译环境,Linux 源码安装 GO 环境
- js 获取图片url的Blob值并预览
- POJ2135 来回最短路(简单费用流)
- 调试一个C#研究生管理信息系统源码
- 一文看透 Redis 分布式锁进化史(解读 + 缺陷分析)
- 1 0.99999的悖论_无限小数与芝诺悖论
- 电脑键盘下划线怎么打_图文详解笔记本电脑键盘失灵怎么办
- android xutil 数据库,Android XUtils3框架的基本使用方法(二)
- hibernate悲观锁,乐观锁
- js在html中加文字走马灯特效,jQuery简单的文字跑马灯特效
- leetcode大纲
- 【学习笔记】bootstrap之CSS组件
- 电机学第一章(磁路的基本定律)
- 单片微型计算机原理及应用考试,单片机原理及应用《微机原理及应用》试卷(A卷)附答案...
- 离线强化学习总结!(原理、数据集、算法、复杂性分析、超参数调优等)
- Excel如何删除空白行
- 【暑期每日一题】洛谷 P5708 【深基2.习2】三角形面积
- 重新回来,介绍一下Android Studio 如何继承腾讯云直播 以及 腾讯云通信
- Domino管理中的一些小而有大用处的技巧
- R语言ggplot2可视化为轴标签添加下标实战:符号下标、百分比下标、带括号的下标