Math.round与Math.ceil相比会产生意想不到的结果

Math.round vs. math.ceil yields unexpected results

本文关键字:Math 意想不到 结果 round ceil      更新时间:2023-09-26

用户可以输入一个值或一个简单表达式作为除法。输出应为小数点后2位的值。例如

8.50 should yield 8.50
4/2 should yield 2.00

但是,如果输入是一个除法,结果是一个分数值,那么输出应该四舍五入。例如

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。。。(因为在这种情况下我想四舍五入)

我不知所措。这里的解决方案是什么?

你不能用简单的方法来做。

问题是,计算机以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为基数操作这些字符串的库。

如果要四舍五入,请使用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

基本区别

Math.floor()总是向下返回或四舍五入,即Math.floor(3.8)将给出3的结果。

Math.round始终返回或四舍五入到最接近的整数,即数学.round(3.8)生成4作为最接近的整数。

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