一、浮点数,是属于有理数中某特定子集的数的数字表示,在计算机中用以近似表示任意某个实数。
具体地说,这个实数由一个整数或定点数(即尾数)乘以某个基数(计算机中通常是2)的整数次幂得到,这种表示方法类似于基数为10的科学计数法。
二、浮点数的浮点就是指,小数点的位置可以是不固定的。

| 【示例】十进制小数8.345,用科学计数法表示,可以有多种方式```javascript 8.345 = 8.345 10^0 8.345 = 83.45 10^-1 8.345 = 834.5 * 10^-2 …

  1. 1、用这种科学计数法的方式表示小数时,小数点的位置就变得不固定了。<br />2、这就是相对于定点数,浮点数名字的由来。 |
  2. | --- |
  3. <a name="nj7Ri"></a>
  4. # 浮点数如何表示数字
  5. 一、浮点数采用科学计数法表示数字,格式如下:
  6. ```javascript
  7. V = (-1)^S * M * R^E
  • S:符号位,取值 0 或 1,决定一个数字的符号,0 表示正,1 表示负
  • M:尾数,用小数表示,例如前面所看到的 8.345 * 10^0,8.345 就是尾数
  • R:基数,表示十进制数 R 就是 10,表示二进制数 R 就是 2
  • E:指数,用整数表示,例如前面看到的 10^-1,-1 即是指数

浮点数 - 图1
二、指数和尾数分配的尾数不同,会产生以下情况

  • 指数位越多,尾数位越少,其表示的范围越大,精度就变差。反之,指数位越少,尾数位则越多,表示的范围越小,但精度就编号。
  • 一个数字的浮点数格式,会因为定义的规则不同,得到的结果也不同,表示的范围和精度也有差异。 | 【示例】假设我们定义如下规则来填充这些 bit:
    - 符号位 S 占 1 bit
    - 指数 E 占 10 bit
    - 尾数 M 占 21 bit
    按照这个规则,将十进制数 25.125 转换为浮点数,转换过程就是这样的(D代表十进制,B代表二进制):
    - 整数部分:25(D) = 11001(B)
    - 小数部分:0.125(D) = 0.001(B)
    - 用二进制科学计数法表示:25.125(D) = 11001.001(B) = 1.1001001 * 2^4(B)
    所以符号位 S = 0,尾数 M = 1.001001(B),指数 E = 4(D) = 100(B)。
    按照上面定义的规则,填充到 32 bit 上,就是这样:
    image.png | | —- |

| 【示例】假设我们定义如下规则来填充这些 bit:
- 符号位 S 占 1 bit
- 指数位 E 这次占 5 bit
- 尾数 M 占 25 bit
按照上面定义的规则,填充到 32 bit 上,就是这样:
image.png | | —- |

浮点数标准

一、早期很多计算机厂商,如IBM、微软等,每个计算机厂商都会定义自己的浮点数规则,不同厂商对同一个数表示出的浮点数是不一样的。
1、这就导致一个程序在不同厂商下的计算机做浮点数运算时,需要先转换成这个厂商规定的浮点数格式,才能再计算。
二、直到1985年,IEEE组织推出了浮点数标准,就是IEEE754浮点数标准。这个标准统一了浮点数的表示形式,并提供了2种浮点格式

  • 单精度浮点数float:32位,符号位S占1bit,指数E占8bit,尾数M占23bit
  • 双精度浮点数double:64位,符号位S占1bit,指数E占11bit,尾数M占52bit

1、为了使其表示的数字范围、精度最大化,浮点数标准还对指数和尾数进行了规定。

  • 尾数 M 的第一位总是 1(因为 1 <= M < 2),因此这个 1 可以省略不写,它是个隐藏位,这样单精度 23 位尾数可以表示了 24 位有效数字,双精度 52 位尾数可以表示 53 位有效数字
  • 指数 E 是个无符号整数,表示 float 时,一共占 8 bit,所以它的取值范围为 0 ~ 255。但因为指数可以是负的,所以规定在存入 E 时在它原本的值加上一个中间数 127,这样 E 的取值范围为 -128 ~ 127。表示 double 时,一共占 11 bit,存入 E 时加上中间数 1023,这样取值范围为 -1023 ~ 1024。

2、除了规定尾数和指数位,还做了以下规定:

  • 指数 E 非全 0 且非全 1:规格化数字,按上面的规则正常计算
  • 指数 E 全 0,尾数非 0:非规格化数,尾数隐藏位不再是 1,而是 0(M = 0.xxxxx),这样可以表示 0 和很小的数
  • 指数 E 全 1,尾数全 0:正无穷大/负无穷大(正负取决于 S 符号位)
  • 指数 E 全 1,尾数非 0:NaN(Not a Number)

    浮点数标准的图例

    float32

    浮点数 - 图4

标准浮点数的表示

| 【示例】把 25.125 转换为标准的 float 浮点数:
- 整数部分:25(D) = 11001(B)
- 小数部分:0.125(D) = 0.001(B)
- 用二进制科学计数法表示:25.125(D) = 11001.001(B) = 1.1001001 * 2^4(B)
所以 S = 0,尾数 M = 1.001001 = 001001(去掉1,隐藏位),指数 E = 4 + 127(中间数) = 135(D) = 10000111(B)。填充到 32 bit 中,如下:
image.png
1、如果用 double 表示,和这个规则类似,指数位 E 用 11 bit 填充,尾数位 M 用 52 bit 填充即可。 | | —- |

浮点数的范围和精度有多大

一、用浮点数表示一个数字,其范围和精度能有多大?

  • 单精度浮点数
    • 范围:-3.4 10^38 ~ 3.4 10 ^38
    • 精度: 1/2^23
  • 双精度浮点数
    • 范围:-1.79 10^308 ~ +1.79 10^308
    • 精度:1/2^52

1、以单精度浮点数 float 为例
(1)它能表示的最大二进制数为 +1.1.11111…1 2^127(小数点后23个1),而二进制 1.11111…1 ≈ 2,所以 float 能表示的最大数为 2^128 = 3.4 10^38,即 float 的表示范围为:-3.4 10^38 ~ 3.4 10 ^38。
(2)它能表示的精度有多小呢?float 能表示的最小二进制数为 0.0000…1(小数点后22个0,1个1),用十进制数表示就是 1/2^23。
2、用同样的方法可以算出
(1)double 能表示的最大二进制数为 +1.111…111(小数点后52个1) 2^1023 ≈ 2^1024 = 1.79 10^308,所以 double 能表示范围为:-1.79 10^308 ~ +1.79 10^308。
(2)double 的最小精度为:0.0000…1(51个0,1个1),用十进制表示就是 1/2^52。
二、虽然浮点数的范围和精度也有限,但其范围和精度都已非常之大,所以在计算机中,对于小数的表示我们通常会使用浮点数来存储。