浮点数

浮点的二进制表示:https://www.ruanyifeng.com/blog/2010/06/ieee_floating-point_representation.html
0.1+0.2不等于0.3:https://cloud.tencent.com/developer/article/1586532

前置知识

IEEE 754
IEEE 754 是 IEEE 二进制浮点数算术标准的简称,在这之前各家计算机公司的各型号计算机,有着千差万别的浮点数表示方式,这对数据交换、计算机协同工作造成了极大不便,该标准的出现则解决了这一乱象,目前已成为业界通用的浮点数运算标准。

IEEE 754 常用的两种浮点数值的表示方式为:单精确度(32位)、双精确度(64位)。例如, C 语言中的 float 通常是指 IEEE 单精确度,而 double 是指双精确度。

64Bits 分为以下 3 个部分:

  • sign bit(S,符号):用来表示正负号,0 为 正 1 为 负(1 bit)
  • exponent(E,指数):用来表示次方数(11 bits)
  • mantissa(M,尾数):用来表示精确度 1 <= M < 2(53 bits)

使用浮点数的原因

十进制数字0.1 无法在用二进制精确的表示出来。
因为 0.1等于二进制的:0.000110011001100110011(0011) //0011 将会无限循环

如何使用浮点数在计算机中近似表示0.1

0.1如何在计算机中表示——>0.1浮点数转二进制:
首先,0.1等于二进制的:0.000110011001100110011(0011) //0011 将会无限循环
相当于1.100...x2^-4

符号位S

由于 0.1 为整数,所以符号位 S = 0

指数位E

我们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,E的真实值必须再减去一个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。

E = -4,实际存储为 -4 + 1023 = 1019,二进制为 1111111011,E 为 11 位,最终为 01111111011

尾数位M

M可以写成1.xxxxxx的形式,其中xxxxxx表示小数部分。IEEE 754规定,在计算机内部保存M时,默认这个数的第一位总是1,因此可以被舍去,只保存后面的xxxxxx部分。比如保存1.01的时候,只保存01,等到读取的时候,再把第一位的1加上去。这样做的目的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第一位的1舍去以后,等于可以保存24位有效数字。

在 IEEE 754 中,循环位就不能在无限循环下去了,在双精确度 64 位下最多存储的有效整数位数为 52 位,会采用 就近舍入(round to nearest)模式(进一舍零) 进行存储

11001100110011001100110011001100110011001100110011001 // M 舍去首位的 1,得到如下
1001100110011001100110011001100110011001100110011001 // 0 舍 1 入,得到如下
1001100110011001100110011001100110011001100110011010 // 最终存储

最终储存结果

0	01111111011	1001100110011001100110011001100110011001100110011010
S       E               M

浮点运算可能产生的偏差

浮点数中 0.1 + 0.2 = 0.30000000000000004 的原因:
参考 https://cloud.tencent.com/developer/article/1586532 后半部分

posted @ 2022-05-11 13:54  Pril  阅读(378)  评论(0)    收藏  举报