浮点数在计算机底层的表示及运算

1.浮点数在计算机底层存储机制

单精度浮点数float占4字节32位,双精度浮点数double占8字节64位。float和double的二进制存储结构都是:符号位+指数位+尾数位

  • 符号位:表示浮点数的正负,0:正 1:负
  • 指数位:控制浮点数数值的大小
  • 尾数位:控制浮点数的精度

float32的位数

符号位 指数位 尾数位
1 8 23

float64的位数

符号位 指数位 尾数位
1 11 52

比如我们要把float32的6.125转化为 二进制的表示

  1. 符号位 正数为0,负数为1,所以6.125的符号位为 1
  2. 指数位 首先把6.125转成二进制的小数.
  • 整数部分 5 转二进制等于 110
  • 小数部分乘以2取整,然后正序排列
0.125 * 2     0
0.25 * 2      0
0.5 * 2       1

小数部分等于101, 结果为110.001 科学计数法表示 1.10001 * 2^2,所以指数为2,由于指数也分正负 2^8 范围是-127 ~ 128 正数需要 + 127 指数位等于127+2 = 129 转化为二进制为 10000001

  1. 尾数位 1.10001 小数点前面的是隐藏位不需要 后面补齐 所以尾数位为 10001000000000000000000

  2. 最终6.125的二进制表示为 01000000110001000000000000000000

2.浮点数的计算机底层加法运算过程

我们都知道float64 中 0.1 + 0.2 != 0.3 那么就来看一下浮点数计算的过程

  1. 首先把0.1和0.2 分别转换成二进制表示为
0.1 0(符号位) 01111111011(指数位) 1001100110011001100110011001100110011001100110011010(尾数位)

0.2 0(符号位) 01111111100(指数位) 1001100110011001100110011001100110011001100110011010(尾数位)
  1. 指数位对阶:一般是用小的指数减去大的 01111111011 - 01111111100 = -1 所以0.1 的尾数位右移一位 (tips:浮点数尾数位隐藏位默认是1)

0.1 尾数位 1.1001100110011001100110011001100110011001100110011010 右移一位

得到 0.1100110011001100110011001100110011001100110011001101(0)

按照01, 0舍去,所以得到

0.1100110011001100110011001100110011001100110011001101

0.10.2 的尾数相加得到

1.1001100110011001100110011001100110011001100110011010

0.1100110011001100110011001100110011001100110011001101

10.0110011001100110011001100110011001100110011001100111
  1. 正规化 根据正规化要求,我们把结果右移一位,并且指数位+1

1.0011001100110011001100110011001100110011001100110011(1)1

1.0011001100110011001100110011001100110011001100110100
  1. 最后得到的二进制为

0 01111111101 0011001100110011001100110011001100110011001100110100

转化十进制

0.30000000000000004

所以现在知道为什么 0.1 + 0.2 != 0.3 了吧

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!