6

我想四舍五入1.006到两位小数,期望 1.01 作为输出

当我这样做的时候

var num = 1.006;
alert(Math.round(num,2)); //Outputs 1 
alert(num.toFixed(2)); //Output 1.01

相似地,

var num =1.106;
alert(Math.round(num,2)); //Outputs 1
alert(num.toFixed(2));; //Outputs 1.11

所以

  • 每次都使用 toFixed() 是否安全?
  • toFixed() 是跨浏览器投诉吗?

请给我建议。

PS:我尝试在堆栈溢出中搜索类似的答案,但无法得到正确的答案。

EDIT:

为什么1.015返回 1.01 而 as1.045返回 1.05

var num =1.015;
alert(num.toFixed(2)); //Outputs 1.01
alert(Math.round(num*100)/100); //Outputs 1.01

然而

var num = 1.045;
alert(num.toFixed(2)); //Outputs 1.04
alert(Math.round(num*100)/100); //Outputs 1.05
4

3 回答 3

4

尝试类似...

Math.round(num*100)/100


1) Multiple the original number by 10^x (10 to the power of x)
2) Apply Math.round() to the result
3) Divide result by 10^x

来自:http ://www.javascriptkit.com/javatutors/round.shtml

(将任何数字四舍五入到 x 小数点)

于 2013-02-27T17:43:14.727 回答
3

这个公式Math.round(num*100)/100并不总是好的。例子

Math.round(0.145*100)/100 = 0.14

这是错误的,我们希望它是0.15

解释

问题是我们有这样的花车

0.145 * 100 = 14.499999999999998

第一步

所以如果我们四舍五入,我们需要在我们的product.

0.145 * 100 + 1e-14 = 14.500000000000009

我假设有时product可能类似于1.000000000000001,但如果我们添加它不会有问题,对吧?

第二步

计算我们应该添加多少?

我们知道 java 脚本中的浮点数是 17 位。

let num = 0.145
let a = Math.round(num*100)/100
let b = a.toString().length
let c = 17-b-2
let result = Math.round(num*100 + 0.1**c)/100
console.log(result)
console.log('not - ' + a )

(-2) - 只是为了确保我们不会落入同样的四舍五入陷阱。

单线:

let num = 0.145
let result = Math.round(num*100 + 0.1**(17-2-(Math.round(num*100)/100).toString().length))/100

附加功能

请记住,以上所有内容都适用于正数。如果四舍五入负数,则需要减去一点。所以最后的 One-liner 将是:

let num = -0.145
let result = Math.round(num*100 + Math.sign(num)*0.1**(17-2-(Math.round(num*100)/100).toString().length))/100
于 2018-07-04T05:48:05.150 回答
2

我意识到这个问题已经相当老了,但即使在提出这个问题 5 年后,我仍然会遇到这个问题。

我知道的这个舍入问题的一个有效解决方案是将数字转换为字符串,获取所需的精度数字并使用数学规则向上或向下舍入。

可以在以下小提琴中找到 Math.round 提供意外舍入的示例和字符串舍入的示例:http: //jsfiddle.net/Shinigami84/vwx1yjnr/

function round(number, decimals = 0) {
    let strNum = '' + number;
    let negCoef = number < 0 ? -1 : 1;
    let dotIndex = strNum.indexOf('.');
    let start = dotIndex + decimals + 1;
    let dec = Number.parseInt(strNum.substring(start, start + 1));
    let remainder = dec >= 5 ? 1 / Math.pow(10, decimals) : 0;
    let result = Number.parseFloat(strNum.substring(0, start)) + remainder * negCoef;
    return result.toFixed(decimals);
}
let num = 0.145;
let precision = 2;

console.log('math round', Math.round(num*Math.pow(10, precision))/Math.pow(10, precision));
// 0.145 rounded down to 0.14 - unexpected result
console.log('string round', round(num, precision));
// 0.145 rounded up to 0.15 - expected result

Math.round 在这里不能正常工作,因为 0.145 乘以 100 是 14.499999999999998,而不是 14.5。因此,Math.round 会将其四舍五入,就好像它是 14.4。如果将其转换为字符串并减去所需的数字 (5),然后使用标准数学规则对其进行四舍五入,您将得到预期结果 0.15(实际上,0.14 + 0.01 = 0.15000000000000002,使用“toFixed”得到一个不错的四舍五入结果)。

于 2018-06-13T10:50:11.480 回答