Open superwoods opened 8 years ago
2016-09-22: 近来,夜观星象。。。 呃 夜观代码,有所心得故而键录于此,聊以自慰!
加法、乘法,哎! 正应了三国曹植七步成诗:“本是同根生,相煎何太急”, 但木木说此处应改为:
”都是754,加乘别积极“ ,老实儿 / 10
// 不符合预期:
for(let i=0, j=100; i<j; i++) { console.log(i++ * 0.1); }
/*
2016-09-22 09:01:52.113 VM6449:1 0
2016-09-22 09:01:52.113 VM6449:1 0.2
2016-09-22 09:01:52.113 VM6449:1 0.4
2016-09-22 09:01:52.113 VM6449:1 0.6000000000000001
2016-09-22 09:01:52.113 VM6449:1 0.8
2016-09-22 09:01:52.114 VM6449:1 1
2016-09-22 09:01:52.114 VM6449:1 1.2000000000000002
2016-09-22 09:01:52.114 VM6449:1 1.4000000000000001
2016-09-22 09:01:52.114 VM6449:1 1.6
2016-09-22 09:01:52.114 VM6449:1 1.8
2016-09-22 09:01:52.114 VM6449:1 2
...
*/
// 符合预期:
for(let i=0, j=100; i<j; i++) { console.log(i++ / 10); }
/*
2016-09-22 09:04:14.831 VM6452:1 0
2016-09-22 09:04:14.831 VM6452:1 0.2
2016-09-22 09:04:14.831 VM6452:1 0.4
2016-09-22 09:04:14.832 VM6452:1 0.6
2016-09-22 09:04:14.832 VM6452:1 0.8
2016-09-22 09:04:14.832 VM6452:1 1
2016-09-22 09:04:14.832 VM6452:1 1.2
2016-09-22 09:04:14.832 VM6452:1 1.4
2016-09-22 09:04:14.832 VM6452:1 1.6
2016-09-22 09:04:14.832 VM6452:1 1.8
2016-09-22 09:04:14.832 VM6452:1 2
...
*/
Java 中不做 类型转换 也存在这样的问题,看图说话:
ps: 感谢我的同事,一位Senior Java程序媛 哦! 人超好、超可爱的😳 so 刚刚吐槽她的IDE的直接拉出去毙了
赞一个,另推荐 math.js
最近读了一下 “JavaScript高级程序设计”, 真是惭愧惭愧,以前都不好好读书的,该死该死啊。。。。
浮点数值的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数。例如,0.1加0.2的结果不是0.3,而是0.30000000000000004。这个小小的舍入误差会导致无法测试特定的浮点数值。例如:
if (a + b == 0.3){
//不要做这样的测试!
alert("You got 0.3.");
}
在这个例子中,我们测试的是两个数的和是不是等于0.3。如果这两个数是0.05和0.25,或者是0.15和0.15都不会有问题。而如前所述,如果这两个数是0.1和0.2,那么测试将无法通过。因此,永远不要测试某个特定的浮点数值。
“JavaScript高级程序设计”中还有很多对于IEEE-754的js相关联问题的阐述,感兴趣的话可以自己去看看,就不一一例举了,
为什么不精确:
js中浮点运算,例如:
无法得到预期结果
0.3
,以上摘选自知乎两位作者的文章,他们答案中说的很详细,原文地址:https://www.zhihu.com/question/20679634
解决思路和吐槽一个朋友:
那么js中解决这个问题的关键就是:
所以简而言之,解决的关键在于小数点上,虽然前几天有个朋友跟说不是这样的,重点是在字符串上,但是我仍然觉得我并没有说错,问题的关键还是去掉小数点嘛!
于是,我们可以这么做:
0.1
放大10
倍变为1
,0.2
放大10
倍变为2
,1 + 2 = 3
3
缩小10
倍,得道正确结果0.3
;如果是这么想来,字符串不是重点吧?只是把数值变为字符串而已,但后面还是用小数点分割数组了。。。
但是我不得不承认,作为非工科出身文科形象思维的我,思维方式中是很难一下子想到这样的抽象思维或者说数学解决方案的,这个思考方式的转换,似乎是一个哲学问题,一个事为什么会这么想,很多时候不是我们决定的,可能会慢慢转变,所以结果就是我还是被你打败了,下次见面不如咱们聊聊怎么画素描吧? 😄开个玩笑~~
不过还是要感谢你,朋友!因为你这个小问题,所以我弄清楚了为什么浮点运算会这样子,短期看来对工作似乎没大帮助,但对于编程的思维方式培养和使用数学方法解决编程中的问题的习惯是有帮助的,这依然是我欠缺的东西,祝福你,也祝福我自己,只有知道自己的不足才能让自己进步不是吗?
再次感谢你!加油!
最后是js实现:
codepen地址:
See the Pen js精确加法 by Super Woods (@superwoods) on CodePen.