Golang深入学习——float

在计算机科学中,浮点数是一种对于实数的近似值数值表现法,利用浮点进行运算,称为浮点计算,这种运算通常伴随着因为无法精确表示而进行的近似或舍入。Go提供了两种size的浮点数,float32和float64。它们的算术规范是由IEEE754国际标准定义,现代CPU都实现了这个规范。

内存中的float32

定义

float32——单精度浮点类型使用32位(4个字节)存储一个浮点数。

IEEE754-2008中定义了它的结构:

符号位 指数 尾数
S EEEEEEEE FFFFFFFFFFFFFFFFFFFFFFF
1位二进制表示符号: 0,正; 1,负 8位二进制表示127偏移量的指数 23位二进制表示23+1位小数部分

例子

以6.9为例子,将生活中常见的十进制转化为机器存储的二进制float。

  1. 将整数和小数部分分别转化为二进制;
1
2
3
6(十进制) = 110(二进制)
0.9(十进制) = 1110011001100......(二进制)
6.9(十进制) = 110.1110011001100......(二进制)
  1. 将小数点左移(或右移)到第一个有效数字之后;
1
110.1110011001100...... => 1.101110011001100......(左移2位)
  1. 填充尾数部分;
1
从小数点后第一位开始,数出23个来,填充到上面float内存结构的尾数部分。默认小数点前面一定有且只有一个1,所以把这个1省略了,这也是为什么定义中尾数是23+1位的原因。
  1. 填充指数部分;
1
2
3
8位表示阶码,无符号是[1,254],0和255用于表示非规格化情况,有符号位是[-126,127],引入偏移量以免使用补码带来计算复杂度。
这个指数就是刚才我们把小数点移动的位数,左移为正,右移为负,用来计算指数的偏移量为127,指数应该是2+127=129。
129(十进制) = 10000001(十进制)
  1. 填充符号位。
符号位 指数 尾数
0 10000001 10111001100110011001100

不精确的原因

  1. 浮点型只有最后一位为5时才能用有限位数的二进制来表示;

  2. 单精度浮点型尾数部分只能保存23位。

内存中的float64

float64——双精度浮点类型使用64位(8个字节)存储一个浮点数。

IEEE754-2008中定义了它的结构:

符号位 指数 尾数
S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
1位二进制表示符号: 0,正; 1,负 11位二进制表示1023偏移量的指数 52位二进制表示52+1位小数部分