如何在JavaScript中四舍五入一个数字?.toFixed()返回一个字符串?

我是不是遗漏了什么?

var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string

.toFixed()是否返回一个字符串?

我想把这个数四舍五入到两位十进制数字。

174081 次浏览

当然它会返回一个字符串。如果要对数值变量进行四舍五入,则应该使用Math.round()。toFixed的作用是将数字格式化为小数点后固定位数用于显示给用户

当它格式化一个数字时,你期望它返回什么?如果你有一个数字,你几乎不能对它做任何事情,例如__abc0等,所以它必须是一个字符串。

因为它的主要用途是显示数字?如果你想四舍五入的数字,使用Math.round()适当的因数。

它返回一个字符串,因为0.1及其幂(用于显示十进制分数)在二进制浮点系统中不可表示(至少不能完全准确地表示)。

例如,0.1实际上是0.1000000000000000055511151231257827021181583404541015625,0.01实际上是0.01000000000000000020816681711721685132943093776702880859375。(感谢BigDecimal证明了我的观点。: - p)

因此(在没有小数浮点数或有理数类型的情况下),将其作为字符串输出是使其精确到显示所需精度的唯一方法。

我通过修改这个来解决这个问题:

someNumber = someNumber.toFixed(2)

...:

someNumber = +someNumber.toFixed(2);

然而,这会将数字转换为字符串并再次解析它,这将对性能产生重大影响。如果您关心性能或类型安全,也请检查其他答案。

我用JavaScript的Number()函数把它转换回数字来解决这个问题

var x = 2.2873424;
x = Number(x.toFixed(2));

Number.prototype.toFixed是一个函数,设计为格式一个数字,然后打印出来。它来自toStringtoExponentialtoPrecision家族。

要四舍五入一个数字,你可以这样做:

someNumber = 42.008;
someNumber = Math.round( someNumber * 1e2 ) / 1e2;
someNumber === 42.01;


// if you need 3 digits, replace 1e2 with 1e3 etc.
// or just copypaste this function to your code:


function toFixedNumber(num, digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(num*pow) / pow;
}

或者如果你想要一个" 本土一样 "函数,你可以扩展原型:

Number.prototype.toFixedNumber = function(digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(this*pow) / pow;
}
someNumber = 42.008;
someNumber = someNumber.toFixedNumber(2);
someNumber === 42.01;




//or even hexadecimal


someNumber = 0xAF309/256;  //which is af3.09
someNumber = someNumber.toFixedNumber(1, 16);
someNumber.toString(16) === "af3.1";

然而,请记住,当你写一个模块时,污染原型被认为是不好的,因为模块不应该有任何副作用。所以,对于一个模块,使用第一个函数

为什么不使用parseFloat呢?

var someNumber = 123.456;
someNumber = parseFloat(someNumber.toFixed(2));
alert(typeof(someNumber));
//alerts number

您可以简单地使用“+”将结果转换为数字。

var x = 22.032423;
x = +x.toFixed(2); // x = 22.03

下面是m93a提供的答案的一个稍微更实用的版本。

const toFixedNumber = (toFixTo = 2, base = 10) => num => {
const pow = Math.pow(base, toFixTo)
return +(Math.round(num * pow) / pow)
}


const oneNumber = 10.12323223


const result1 = toFixedNumber(2)(oneNumber) // 10.12
const result2 = toFixedNumber(3)(oneNumber) // 10.123


// or using pipeline-operator
const result3 = oneNumber |> toFixedNumber(2) // 10.12

提供一个为什么它必须是字符串的例子:

如果你格式化1.toFixed(2),你会得到'1.00'。

这和1不一样,因为1没有两个小数。


我知道JavaScript并不是一种确切的性能语言,但如果你使用以下内容,你可能会获得更好的性能: roundedValue =数学。Round(值* 100)* 0.01

对于像我这样偶然遇到这个古老问题的人,一个现代的解决方案:

const roundValue = (num, decimals = 2) => {
let scaling = 10 ** decimals;
return Math.round((num + Number.EPSILON) * scaling) / scaling;
}

裁判:https://stackoverflow.com/a/11832950

可能来不及回答,但您可以将输出与1相乘以再次转换为数字,这里是一个例子。

const x1 = 1211.1212121;
const x2 = x1.toFixed(2)*1;
console.log(typeof(x2));

你应该像下面这样使用它。

var someNumber: number = 0.000000;
someNumber = Number(someNumber.toFixed(2))

为什么不将结果乘以1,即

someNumber.toFixed(2) * 1

使用toFixed()Math.round()时要小心,由于浮点数系统,它们可能会产生意想不到的结果:

function toFixedNumber(num, digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(num*pow) / pow;
}


console.log(toFixedNumber(130.795, 2, 10));
// 130.79 (incorrect)
console.log(toFixedNumber(100.795, 2, 10));
// 100.8


console.log(+130.795.toFixed(2));
// 130.79 (incorrect)
console.log(+100.795.toFixed(2));
// 100.8

我建议使用Lodash的_.round()函数:https://lodash.com/docs/4.17.15#round

_.round(130.795, 2);
// 130.8