JS中的舍入:不一致和意外的行为
我正在处理相对较小且简单的数字。我第一次试图做出四舍五入(数字后2个符号)与臭名昭着的toFixed。这是一个已知的问题:有时它不正确。但让我印象深刻的是,它也可以不一致:JS中的舍入:不一致和意外的行为
(0.395).toFixed(2); // "0.40"
(0.295).toFixed(2); // "0.29"
这些数字都非常相似,数字后3个迹象,但不同的行为。
所以,我决定切换到使用Math.round。不久,我遇到了另一个问题:
Math.round(0.35055 * 10000)/100; // produces 35.05 instead of 35.06
Math.round也有问题吗?那么,应该使用什么方法?
不幸的是,JavaScript已知存在如下精确问题,这些问题在以下问题中得到了更好的解释:Is floating point math broken?,正如评论中指出的那样。
如果您需要更高程度的数值准确性,我建议您使用库,如BigNumber,它也有自己的toFixed
方法。
你的例子是这个样子:
var a = new BigNumber('0.35055');
a = a.times(10000)
a = a.dividedBy(100)
console.log(a.toFixed(2)); //would log "35.06"
为了简便起见,你也可以连锁经营,像这样:a.times(10000).dividedBy(100).toFixed(2)
我通过以下解决方法解决了我的问题: 'Math.round((0.35055 * 100)* 100)/ 100;' 但显然,您的解决方案更好,谢谢。 – Zaziro
我想这是事先设计好的。请记住,这些数字存储在基数2中,因此在转换为基数10时会损失精度。如果您想了解这些转换为什么看起来不一致,则必须查看这些转换。如果您想精确保留固定的小数位数,则可以使用整数进行操作并仅转换用于显示。
FWIW最后一个问题发生在Math.round之前:'0.35055 * 10000' - >'3505.4999999999995' –
为什么'0.35055 * 1000'等于'3505.4999999999995'而不是'3505.5'? – Manav
检查这些答案:[这里](https://stackoverflow.com/q/5490687/1823841),[这里](https://stackoverflow.com/q/10768083/1823841) –