当前位置:   article > 正文

ieee754双精度浮点数转换_消灭烦人的IEEE754困惑--知识梳理

ieee754双精度在线转换

3f7bede168fd286fa38719c2eab84834.png

引言

最近被数值计算的问题困扰,索性做一个梳理,与君分享,温故而知新。

在计算机的世界中,浮点数的表示范围有限。存在无穷多个不能用浮点数表示的数,或者说,浮点数只是近似地表示某一个数。有些情况下0.1+0.2!=0.3。

目录

  1. 什么是IEEE-754?
  2. 指数偏移值--阶码
  3. 规约与非规约以及其它特殊值
  4. 浮点数的舍入
  5. 浮点数的运算----加法运算
  6. 浮点数的运算----乘法运算

什么是IEEE-754?

IEEE二进制浮点数算术标准(IEEE 754)是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。这个标准定义了表示浮点数的格式(包括负零-0)与反常值(denormal number),一些特殊数值(无穷∞与非数值NaN),以及这些数值的“浮点数运算符”。 常见的四种浮点数值表示方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。C语言的float通常是指IEEE单精确度,而double是指双精确度。
https://zh.wikipedia.org/wiki/IEEE_754​zh.wikipedia.org

c4cb82741716d15c505bcd4603385071.png

我以网上能找到的ieee 754 float32在线转换器为例,简单易懂。标准的ieee 754格式由三部分组成,符号位Sign,指数项expoent,以及尾数部分mantissa。它的值可以用

来进行表示。

指数偏移值--阶码

浮点数表示法中指数域的编码值,等于指数的实际值加上某个固定的值,IEEE 754标准规定该固定值为

。其中的
为存储指数的比特的长度。

以单精度浮点数为例,它的指数域是8个比特,固定偏移值是

。此为有符号数的表示方式,
单精度浮点数的指数部分实际取值是从-126到127。(其中-127和128被用作特殊值处理,我们一会儿会讲到)若指数实际值位12(十进制),那么在该编码模式下的编码值就为12+127=139。

你肯定心中会问?干嘛要以实际值加上固定的偏移值的办法表示浮点数的指数???其实好处是可以用长度为e个比特的无符号整数来表示所有的指数取值。我们常常把指数部分称为:阶码

规约与非规约以及其它特殊值

罗列了一下,由于这种阶码+尾数的表示方式,使得浮点数的值形式有多种。

  • 零:指数0,小数0;
  • 非规范化:指数0,小数 大于0小于1;
  • 规范化:指数
    ,小数[1,2);
  • 无穷:指数
    ,小数0;
  • NaN:指数
    ,小数非0。

以上规律直接总结为三条:

  1. 如果指数是0并且尾数的小数部分是0,这个数±0(和符号位相关)
  2. 如果指数 =
    ,并且尾数的
    小数部分是0,这个数是±∞(同样和符号位相关)
  3. 如果指数 =
    ,并且尾数的
    小数部分非0,这个数表示为非数(NaN)。

在此以32位单精度浮点为例,我来列一下这些类别下的数字。懂得了这些规律后,再来看规约数的表达,其实简单的一笔

类别 正负号 实际指数 有偏移指数 指数域 尾数域 数值

零 0 -127 0 0000 0000 000 0000 0000 0000 0000 0000 0.0

最小规约数 * -126 1 0000 0001 000 0000 0000 0000 0000 0000 ±2−126≈ ±1.18×10-38

最大的规约数 * 127 254 1111 1110 111 1111 1111 1111 1111 1111 ±(2−2−23) × 2127≈ ±3.4×1038

正无穷 0 128 255 1111 1111 000 0000 0000 0000 0000 0000 +∞

浮点数的舍入

好了,在了解数长什么样以后,再来说说舍入的问题。从硬件的角度来说,舍入是因为数bit位宽高于寄存器的bit位宽,那只能将多出来的位丢掉。实际上丢掉的方式有许多。IEEE列出了4种不同的标准:

  1. round to nearest. 舍入到最接近,在一样接近的情况下偶数优先(当存在两个数一样接近的时候,则取其中的偶数(在二进制中是以0结尾的))
  2. 朝正无穷舍入 ceil(1.324) = 2
  3. 朝负无穷舍入 floor(1.234)= 1
  4. 朝0舍入,就是截断(int) 1.324= 1

浮点数的运算

浮点数加法

浮点数的加法运算分成下面步骤:

  • 对阶: 对齐阶码,使两数的小数点位置对齐,小阶向大阶对齐。
  • 尾数求和:对阶完对尾数求和。
  • 规格化:尾数必须规格化成1.M的形式。
  • 舍入:由于规格化的引入,必然导致精度的损失。
  • 校验判断:最后一步是校验结果是否溢出。若阶码上溢则置为溢出,下溢则置为机器零。

以0.2+0.4为例:

对阶过程:

0.2 => 0 01111101 (0)11001100110011001100110

0.4 => 0 01111101 (1)10011001100110011001100

尾数求和:

(0)11001100110011001100110 + (1)10011001100110011001100 => (10)01100110011001100110010

尾数规格化:

0 01111101 (10)01100110011001100110010 => 0 01111110 (1)00110011001100110011001

注意0已经被移除了这就是舍入

校验判断

0.2 + 0.4 => 0 01111110 (1)00110011001100110011001 => 1.1999999285/2 => 0.5999999643 (并不等于0.6)

当然知道了这些 还不算,我来说说怎么做乘法。

浮点数乘法

我以这张图来说明这个过程。

29267ffee28f8cab70fcbc8ecf19a6b6.png

浮点乘法包括符号位异或、指数相加和尾数相乘三部分。

  1. 首先符号位和指数位运算相对简单,只涉及到异或操作。
  2. 尾数相乘部分较复杂,涉及多个部分积的产生及累加,以及累加结果的舍入。因此,提高浮点乘法器的性能主要是针对尾数相乘部分的。现行的浮点乘法器大多采用图中的结构,由于尾数在舍入过程中可能溢出,舍入后还需要规格化,因此舍入逻辑需要两个规格化过程(即舍入前规格化和舍入后规格化)。

好了说到这儿,谁在提精度问题,直接开启fighting模式。

80a17ae2baa8b15c64e4745cfe0228b8.png

有关乘法器的内部设计和truncation等近似技术在神经网络冗余计算中的作用,我将在下一篇介绍中进行介绍。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/258417
推荐阅读
  

闽ICP备14008679号