数据的表示与运算-浮点数
前言:
- 计算机中,数字分为定点数和浮点数。相对于浮点数,定点数比较好理解,原码补码反码移码。而浮点数十分繁杂。
- 关于浮点数的繁杂,我觉得最好的解释就是,\(William\ M. Kahan\)因其在浮点数运算标准的制定上的突出贡献而获得图灵奖。\(Kahan\)也是浮点数\(IEEE754\)标准的主要设计师。
初识浮点数:
- 假如说我们现在想要表示光速这样一个数值,我们可以怎么做?
- \(1:\)采用整数方式把他写出来,那么就是\(300...00m/s\)。这样数字十分的长,与计算机不好保存。
- \(2:\)采用科学计数法,那么就是\(3*10^{8}m/s\),那么如果我现在想保存这个数字,那么我只需要记录三个信息,第一个是\(3\),第二个是\(10\),第三个是\(8\)。
- 两种方法比较:
- 很明显第一种方法需要我们用更多的存储空间来保存它,而对于科学计数法,我们并不需要记录那么多的数却能表示同样的数值。
- 对于计算机而言,只能认识\(0/1\)符号,这在硬件实现上更为方便简单。所以我们这时候可以把\(10\)这个底数给取消掉,计算机默认他是\(2\),这样我们就可以只用保存两个数字,来表示这样一个大的数字。
- 对于表示电子的质量,太阳系的直径,这样非常极端的数字时,科学计数法的优势显得更为明显。它更方便。
- 但我们也可以发现,如果说我要表示的数字不是\(300...000\),而是\(29935...13\)这样的数字,而我科学计数法采用\(2.9*10^{8}\),那么我势必丢掉一些精度。
- 在我的理解看来,浮点数的表示是用精度来换取表示范围。
- 所以这里我们似乎也能理解为什么在\(c\)语言中,\(double\)比\(float\)能表示更高的精度,因为\(double\)位数更高,他能表示更多的小数。
- 也能多少的理解浮点数为什么叫浮点数,因为随着我数字的指数不同,小数点的位置也在随之改变。
浮点数的表示:
浮点数规格化:
- 先看门见山讲一下什么叫规格化。
规格化规定尾数的最高数位必须是一个有效值。
- 通过以上的阅读,我们可以发现,要想让精度最大化,那么我们就需要让尾数部分尽可能的保存有效的数字。
- 比如说对于这两个数(二进制)
- \(2^{10}*0.01\)和\(2^{01}*0.1\).
- 这两个数是相等的,但是第二个数明显可以在尾数上少保存一位\(0\),所以这时候我们可以对浮点数进行规格化,让他能表示更高的精度。
- 所谓规格化,是指通过一定的操作改变浮点数的尾数和阶码的大小,让浮点数(非0)的尾数在最高位保证是一个有效值。
- 有如下两种方法:
- 左规:当浮点数运算结果为非规格化时需要进行规格化处理,将尾数算术左移一位,并将阶码减一(二进制)。(左规可能需要进行多次)
- 右规:当浮点数运算尾数出现溢出时,也就是双符号为出现了\(01/10\),需要将尾数算术右移一位并将阶码加一。右规只进行一次。
- 那么规格化的浮点数的尾数的范围就是\(\frac{1}{2}\leq |M|\leq 1\)。
- 分析:
- 假设用原码来表示尾数:
- 正数:
- 数的最大值是\(0.11...111\),此时真值为\(1-2^{-n}\)。
- 数的最小值时\(0.10...000\),此时真值为\(\frac{1}{2}\)。
- 绝对值的范围为\([\frac{1}{2},1-2^{-n}]\)。
- 负数:
- 数的最大值是\(1.10...00\),此时真值为\(-\frac{1}{2}\)。
- 数的最小值是\(1.11...11\),此时真值为\(-(1-2^{-n})\)。
- 绝对值的范围是\([\frac{1}{2},1-2^{-n}]\)。
- 假设用补码来表示尾数:
- 正数:
- 负数:
- 负数的最大值为\(1.011...1\),最小值为\(1.00...0\)。
- 绝对值得范围为\([\frac{1}{2}+2^{-n},1]\)。
- 这里需要注意。尾数的最大值不是\(1.10...00\)这样的形式,因为\(1.10...000\)不是一个规格化数。
- 这里我查了一些资料,有两种说法我比较认可,第一个是对于\(1.10000\),我可以接着对他规格化到\(1.00000\);第二个是方便机器的设计,对于原码,我可以判断他的尾数最高位是不是\(1\)来判断他是否规格化,对于补码,我可以判断他的数符和尾数最高位是否相同来判断他是否规格化。
IEEE754标准:
按照\(IEEE754\)标准,浮点数表示格式如下:
为了最大幅度的增大浮点数表示精度,我们尾数最高位如果为\(1\)我们将其隐藏。举个例子,假如说尾数是\(1011\),那么我们存储\(011\)。
\(float\)和\(double\)都是满足\(IEEE754\)标准的浮点数。
阶码以移码形式存在。对于短浮点数\(float\),偏置值为\(127\),对于长浮点数\(double\),偏置值为\(1023\)。
那么可以这么求:我先将\(E\)的看成补码形式求出其值,然后减去\(127/1023\)就是他的移码代表的值。
- \((-1)^s*1.M*2^{E-127}\)(短浮点数)。
- \((-1)^s*1.M*2^{E-1023}\)(长浮点数)。
浮点数的加减运算:
数据的表示与运算-浮点数
原文:https://www.cnblogs.com/zxytxdy/p/11909332.html