参考书籍 《程序是怎样跑起来的》
二进制小数表示
在计算机中,一切数据都是以二进制的形式进行表示,小数也不例外。
若将一个十进制的小数化为二进制小数,其简单规则如下图所示:
但是像1011.0011这样带小数点的表现形式,完全是纸面上的二进制数表现形式,在计算机内部是无法直接使用的,且计算机若采用定点数的形式来表示小数的话,则限制了其表示范围以及空间分配的不合理;
那么如何更加有效地描述小数呢?
浮点数的基本概念
在很多编程语言中都提供了两种表示小数的数据类型,分别是双精度浮点数和单精度浮点数。双精度浮点数类型用64位、单精度浮点数类型用32位来表示全体小数。
在C语言中,双精度浮点数类型和单精度浮点数类型分别用double和float来表示。这些数据类型都采用所谓的浮点数来表示小数。那么,浮点数到底是什么呢?
像这样使用与实际小数点位置不同的书写方法来表示小数的形式称为浮点数。
与浮点数相对的是定点数,使用定点数表示小数时,小数点的实际位置固定不变。例如,用定点数来表示的话即为123.45和0.012345。
这样,浮点数是指用符号、尾数、基数和指数这四部分来表示的小数。因为计算机内部使用的是二进制数,所以基数自然就是2。
IEEE 32 与 IEEE 64
前面提到了,在计算机中实际上有两种浮点数标准,分别为双精度浮点数(64位)与单精度浮点数(32位),并且实际存储的内容为符号、指数以及尾数三个部分:
双精度浮点数能够表示的正数范围是 ~ ,负数范围是 ~。
单精度浮点数能够表示的正数范围是 ~ ,负数范围是 ~ 。
并且在这些范围中,有些数值是无法准确表示的,如 0.1 等,故而在使用浮点数做运算的时候需要额外留意。
符号部分的规则
符号部分的规则比较简单,用1表示负数,0表示正数。
指数部分的规则
指数部分采用"EXCESS"系统表现。
所谓EXCESS是“剩余的”的意思。简单来讲,就是在一个范围中找到一个中间值来表示0,那么小于这个中间值的为负值,大于这个中间值的为正值。
使用这种方法主要是为了表示负数时不使用符号位。在某些情况下,在指数部分,需要通过“负xx次幂”的形式来表示负数。EXCESS系统表现是指,通过将指数部分表示范围的中间值设为0,使得负数不需要用符号来表示。
尾数部分的规则
尾数部分使用的是将小数点前面的值固定为1的正则表达式。
而由于第1位必须是1,第1位的1在实际的数据中无需保存。
并且不难理解的是,向左移n次则最终指数部分的实际值为
-n,向右移n次则最终指数部分的实际值为n。
总结
小数是以浮点数的形式在计算机中表示,而浮点数在计算机中的表示则通过特定的格式与规则来进行存储:
也正因如此,我们可以知道诸如0.1这种小数是无法在计算机中准确描述的,所以在遇到浮点数比较与计算等问题时,要额外注意出错的情况,能转换成整数运算的尽量转换成整数运算。