Math.round与math.ceil会产生意外结果

时间:2015-12-29 01:04:09

标签: javascript

用户可以输入值或简单表达式作为除法。 输出应为2位小数的值。 e.g。

8.50 should yield 8.50
4/2 should yield 2.00

但是如果输入是一个除法导致小数值,则输出应该向上舍入。 e.g。

500/3 should yield 166.67

使用以下计算:

var fieldVal = 500/3;
fieldVal = Math.ceil(fieldVal * 100) / 100;
fieldVal; // yields 166.67 - good

但如果fieldVal = 8.88计算产生8.89

如果我使用:

var fieldVal = 8.88;
fieldVal = Math.round(fieldVal * 100) / 100;
fieldVal; // yields 8.88 - good

可是:

var fieldVal =  500/6.95;
fieldVal = Math.round(fieldVal * 100) / 100;
fieldVal; // yields 71.94

但我想要71.95,因为500/6.95会产生71.942 ...(因为我想在这种情况下进行整理)

我很茫然。这里有什么解决方案?

3 个答案:

答案 0 :(得分:4)

你不能以一种简单的方式做到这一点。

问题是计算机将数字存储在基数2中,并且具有有限的精度。然后,您的8.88变为

8.88000000000000078159700933611020445823669433593750

根据您的规则,它会向上舍入为8.89

解决方案可能是将您的数量乘以100(在源代码中,而不是使用JS),并在最后将它们除以100。

var fieldVal100 = 888; // 8.88 * 100
fieldVal100 = Math.ceil(fieldVal100);
var fieldVal = fieldVal100 / 100; // 8.88

var fieldVal100 = 50000/3; // 500/3 * 100
fieldVal100 = Math.ceil(fieldVal100);
var fieldVal = fieldVal100 / 100; // 166.67

var fieldVal100 = 50000/6.95; // 500/6.95 * 100
fieldVal100 = Math.ceil(fieldVal100);
var fieldVal = fieldVal100 / 100; // 71.95

另一个解决方案是将数字存储为字符串而不是数字,并使用一些库在基数10中操作这些字符串。

答案 1 :(得分:2)

如果您要整理使用ceil()而不是round()

fieldVal = Math.ceil(fieldVal * 100) / 100;

如果你围绕7194.2,你将获得7194而不是7195,因此会导致71.94

8.88 * 100前往8.89的原因是因为计算机存储十进制数字的方式。因为它们不能代表所有可能的小数,所以它们近似于一定程度。因此8.88 * 100 = 888.0000000000001使用ceil会导致889

答案 2 :(得分:0)

基本区别...

Math.floor()返回或舍入总是向下,即 Math.floor(3.8)将得出结果为 3

Math.round总是返回或四舍五入到最近的整数,即 Math.round(3.8)会产生 4 作为最接近的整数可能。

Math.ceil()返回或四舍五入总是向上,即 Math.ceil(3.8)产生 4 作为最接近的向上整数。