浅剖0.1 + 0.2 = ?

发布时间:2024-07-03 11:01

溯源

数字计算机当中是以二进制存储,所以这里我们需要先知道十进制转二进制的规则,和二进制转十进制的规则
十进制转换二进制
分两种规则:

  1. 整数转二进制:除2取余,逆序排列。
  2. 小数转二进制:乘2取整,正序排列

怎么理解这两句:比如 9.375这个数字,整数是9,小数是0.375

整数9转成二进制就是: 1001
浅剖0.1 + 0.2 = ?_第1张图片

那么小数0.375转成二进制就是:011
浅剖0.1 + 0.2 = ?_第2张图片
那么9.375转成二进制就是 1001.011

可利用下面方法验证

console.log((9.375).toString(2))
console.log(Number.prototype.toString.call(9.375,2));
console.log(Number.prototype.toString.call(Number(9.375),2));

浅剖0.1 + 0.2 = ?_第3张图片

同样二进制转十进制

  1. 小数点前:从右往左用二进制的每个数乘以2的相应次方递增
    浅剖0.1 + 0.2 = ?_第4张图片
  2. 小数点后:从左往右用二进制的每个数乘以2的相应负次方递增
    image.png

IEEE 754 双精度64位浮点数
浅剖0.1 + 0.2 = ?_第5张图片
十进制有个叫科学计数法表示:
浅剖0.1 + 0.2 = ?_第6张图片
浅剖0.1 + 0.2 = ?_第7张图片

所以

0.1的二进制
e = -4;
m = 1.1001100110011001100110011001100110011001100110011010 (52位)
浅剖0.1 + 0.2 = ?_第8张图片
0.2的二进制
e = -3;
m = 1.1001100110011001100110011001100110011001100110011010 (52位)
然后我们把它相加,这里有一个问题,就是指数不一致时,一般是往右移,因为即使右边溢出了,损失的精度远远小于左移时的溢出
所以转化后为

e = -3; m = 0.1100110011001100110011001100110011001100110011001101 (52位)
+
e = -3; m = 1.1001100110011001100110011001100110011001100110011010 (52位)

得到

e = -3; m = 10.0110011001100110011001100110011001100110011001100111 (52位)

保留一位整数

e = -2; m = 1.00110011001100110011001100110011001100110011001100111 (53位)

超过了52位,做四舍五入
舍入与原来的数最接近的,原则是保留偶数最终的二进制数

1.0011001100110011001100110011001100110011001100110100 * 2 ^ -2

=0.010011001100110011001100110011001100110011001100110100

转化为十进制为0.30000000000000004

如何避免这个事情的发生

我们认为可以理解的数,在计算机内部它反而是一个无限循环的小数,
它没有办法,它的尾数的尾数只有52位,它只有截断,进行规格化,进行舍入处理的时候可能就会导致一个精度的偏差,所以得到的是一个相对精准的结果但不是绝对的精准
有什么办法让0.1+0.2等于0.3
(0.2*100 + 0.1*100)/100
那就是避免计算的时候出现小数位

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号