浮点数总结

浮点数与其构成

为什么学习浮点数?

对于浮点数,我一直都是抱着深入其基础实现的想法,但是之前一直没有进行底层知识的学习。终于在这几周,我开始恶补底层的知识,虽然对于大部分人来说浮点数以及对于浮点数的操作都不需要知道其内部的实现,不过我认为我们可以不用去实现,但是作为知识面我们至少还是要了解一二的。

比如在程序语言中经常可以看到的问题:0.1 + 0.2 != 0.3 问题。

当然上面这个问题归根到底主要是小数在二进制中的计算方案采用一种乘2取1的方法

浮点数的基本格式

我们知道计算机底层对于数的表示都是 0101xxxx... 这样的二进制码,在整数的二进制中我们将有符号数的存储单元(这里所说的存储单元与int32 = 4 bytes对应)最高位置设为符号位,1表示整个数为负数。

十进制如何进行浮点数表示

例如:

  • 0.000001 = 1.0 * 10^-6
  • 30000 = 3.0 * 10^4

二进制浮点数表示

所以我们可以对这种认识进行二进制翻译

1.0 * 10^6 = 1 * binary(10^-6)

3.0 * 10^4 = 11 * binary(10^4)

存储在计算机里的二进制浮点数表示

但是我们不能将一个表达式直接存储在计算机中,虽然我认为是有办法可以做到,但是这并不划算,所以我们需要一套性价比更高的方案。

于是乎我们就需要去制定一套存储格式,去规定浮点数的正负,指数次数,以及实际有效的数。

另外我们也可以发现对于30000这样的数字我们也可以表示为30 * 10^3 == 3 * 10^4,而我们称等号右边是对等号左边的规格化,同理二进制也可以做这样的规格化,因为二进制只有0和1,所以我们只会在左边数为1的时候进行一次移位,这样我们省下这一位的空间了,为浮点数提供更大的表达范围。

浮点数的三部分:符号位指数段尾数段。值得一提的是,浮点数的符号位这种表示与整数符号位的设计思维并不一样。

1
浮点数 = (-1)^S * fraction(尾数) * 2^exponent(指数)

以下是 IEEE754标准的f32

31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12
符号位 exponent exponent fraction
11 10 9 8 7 6 5 4 3 2 1 0
fraction

具体的计算

1.如果0,32位存储全为0

2.如果不为零,进行上述的计算方案,负数在符号位置1,进行二进制的计算将思维中的十进制浮点数转换为二进制。

计算机底层如何处理我不清楚,这里我根据浮点数的算数处理留下以下结论:

  • 如果存在整数位,exponent = 整数位的位数 - 1, fraction 扔掉最高位的1
  • 如果不存在整数位,我们需要找到小数位二进制的第一个1,1前面的0 以 exponent = 0的数量 来表示

反馈

为了更简单的得到反馈:我使用了浏览器为载体,下面是我的代码仓库

https://github.com/sunboyZgz/interesting/blob/main/src/components/009.vue


浮点数总结
http://example.com/2022/10/12/float-numeric/
作者
sunboyZgz
发布于
2022年10月12日
许可协议