bug复盘之除数为0会怎样?
0
阅: - 评:0 - 积分:摘要:说起来这是一个比较坑爹的问题,因为公司里的前端和后端同事均多次掉入坑中,很有必要写一篇笔记做下记录......
一、先从功能说起
项目里有个修改价格利率的功能。说直白点儿就是,修改价格后,会根据算法自动计算出一个新值。这么说也不利于理解,还是放上一张图吧。见下图↓↓↓
相关同事写的算法如下:
// 修改价格利率
handlePriceChange(val) {
val.spec_price_rate = (((val.sale_price - val.cost_price) / val.sale_price) * 100).toFixed(1)
}
上面的算法可能不太直观,我们再拆分的更细一些和补充上注释。
// 修改价格利率
handlePriceChange(val) {
const price = (val.sale_price - val.cost_price) / val.sale_price // (售价 - 成本价) / 售价
val.spec_price_rate = (price * 100).toFixed(1) // *100是为了转换成百分比,toFixed(1)是为了保留小数点后1位
}
现在,原来的一行算法拆分成了两行代码,再加上注释,阅读起来已经很轻松了。
再仔细看看这段代码,有没有问题呢?
二、异常显示Infinity???
乍眼看上去可能发现不了问题,直到测试(@老王)提了一个让我很懵逼的bug。经过分析后,我这才发现这段代码确实是有问题的。bug复现如下图↓↓↓
-Infinity
???这是什么鬼?!
你以为这个“乱码”Infinity
是手动输入的?其实他只是输入了一个0
而已。
说真的,起初我并没有在意除数为0这个极端条件。但不巧的是,如果用户输入了0
,算法就变成了: -成本价 / 0,也就意味着除数为0。
可能正在阅读的你会在脑海中快速闪现出一个疑问:0不是不可以做除数吗???
我的第一反应也是这样,但在一番搜索之后,我发现了新大陆!两个数相除,结果并不一定是常见的数字。有可能为NaN
,还有可能为Infinity
。
2.1、除法运算符
下方仅列出一些特殊情况,更详细说明参见w3school的文档→→→除法运算符。
除法运算符由斜杠(/)表示,左操作数是被除数,右操作数是除数。
var iResult = 88 / 11;
与乘法运算符相似,在处理特殊值时,除法运算符也有一些特殊行为:
如果结果太大或太小,那么生成的结果是 Infinity 或 -Infinity。
如果某个运算数是 NaN,结果为 NaN。
Infinity 被 Infinity 除,结果为 NaN。
Infinity 被任何数字除,结果为 Infinity。
0 除一个任何非无穷大的数字,结果为 NaN。
Infinity 被 0 以外的任何数字除,结果为 Infinity 或 -Infinity。
通过上方列举的一些特殊行为可以发现,在除法运算中,确实是存在结果为Infinity或-Infinity的情况。但上方的这些特殊行为中,并没有提到0做除数的情况。
既然文档中也没有特殊说明,那0到底可不可以做除数呢?
来做个小测试吧,打开浏览器的控制台,故意构造一个除数为0的除法,看看会出现什么吧!如下图↓↓↓
可以看到,当除数为0时,以上几组结果均为Infinity
或-Infinity
。
2.2、如何避免此问题
现在,我们知道了Infinity
是怎么产生的,那解决方案自然也就有了。只需要判断售价是否为0,如果为0则直接输出结果并中止掉后面的程序即可。相关代码见下方。
// 修改价格利率
handlePriceChange(val) {
// 如果售价为0,则直接输出 0.0 并中止掉程序
if (Number(val.sale_price) === 0) {
val.spec_price_rate = '0.0'
return
}
const price = (val.sale_price - val.cost_price) / val.sale_price // (售价 - 成本价) / 售价
val.spec_price_rate = (price * 100).toFixed(1) // *100是为了转换成百分比,toFixed(1)是为了保留小数点后1位
}
三、结束语
虽然是一个很简单的除法算法,但里面也暗藏着坑在里面。
有可能在阅读此文的你会觉得没什么,那我就再告诉你们一个小秘密吧。前端同事先踩的坑,几个月后,开发新功能时,后端同事同样踩坑。[:笑哭]
如果我们在开发阶段再仔细一点儿,多做一些极端条件的处理,bug就会少很多,我们的代码才会更加健壮!共勉!!
转载声明:
若亲想转载本文到其它平台,请务必保留本文出处!
本文链接:/xwzj/2023-01-10/what-happens-when-the-divisor-is-0.html
若亲不想直保留地址,含蓄保留也行。艺灵不想再看到有人拿我的技术文章到他的地盘或者是其它平台做教(装)程(B)而不留下我的痕迹。文章你可以随便转载,随便修改,但请尊重艺灵的劳动成果!谢谢理解。
亲,扫个码支持一下艺灵呗~
上一篇: Vite2项目优化之线上功能有异常,如何快速排查问题 下一篇: 2023年敬业福获取方法