[JS][深度]关于计算机无法精确处理小数的问题

1、问题

给定一个变量 temp, 变量初始值为0.1,每次递增0.1:

let temp = 0.1;
while (temp<10){
    temp+=0.1;
    console.log(temp)
}

打印值部分序列如下:

0.4>0.5>0.6>0.7>0.799999…>0.899999…>0.9999…>1.09999…>0.9999…>1.09999…>0.99999…

注意到从0.7>0.7999…的部分开始,0.7+0.1=0.7999999999

继续看以下代码:

<html>	
	<script type="text/javascript" >
		window.onload =function(){
				alert(0.4==0.40000000000000001);//true
		}
	</script>
</html>

很神奇

大概试了一下,从小数位后18位起,计算机就识别不了了。

2、解释

典型的精度问题,其实不是我们代码本身的问题。

计算机是以二进制的方式来存储数据,代码中的十进制小数,计算机都会替我们转换为二进制去进行计算。

作为小数,在二进制的情形下,会出现无穷小数的状况。

举个例子

 

十进制15.43转换成二进制是多少

整数部分:

15%2=1

(15%2)%2=1

((15%2)%2)%2=1

(((15%2)%2)%2)%2=1  

除二取余,逆序排列:1111

小数部分:

Math.ceil(0.43*2)=0

Math.ceil((0.43*2)*2)=1

Math.ceil(((0.43*2)*2)*2)=1

Math.ceil((((0.43*2)*2)*2)*2)=0

Math.ceil(((((0.43*2)*2)*2)*2)*2)=1

Math.ceil((((((0.43*2)*2)*2)*2)*2)*2)……

……

乘二取整,顺序排列:01101……

把计算出来的整数部分和小数部分放到一起,中间加上小数点

所以15.43二进制为:1111.01101……

 

可以发现,在计算整数部分的过程中,2的0次方=1,这是整数最小单位,二进制整数以"0"或"1"结尾,相应10进制则表现为奇数或者偶数,涵盖了所有自然数,所以不会出现无穷序列的情况。

但小数部分如果不正好等于0.5的n次幂,如例子中的0.43,则二进制转换的这个过程永远无法结束。

3、解决方案

所以小数的计算,在项目中进行的应用时,不能直接将其交给计算机进行处理,否则大概率会出问题。

人工干预的方法:将小数类型数据转化成0.5的n次幂家族中的一员,n由项目实际所需的精度而定。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值