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

Der*_*air 154 javascript types rounding

我在这里错过了什么吗?

var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Run Code Online (Sandbox Code Playgroud)

为什么.toFixed()返回一个字符串?

我想将数字四舍五入到2位小数.

m93*_*93a 150

Number.prototype.toFixed是一种用于在打印之前格式化数字的功能.这是来自家庭的toString,toExponentialtoPrecision.

要舍入一个数字,你会这样做:

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

// if you need 3 digits, replace 1e2 with 1e3 etc.
Run Code Online (Sandbox Code Playgroud)

.

或者如果你想要一个类似本机的功能,你在这里:

Number.prototype.toFixedNumber = function(x, base){
  var pow = Math.pow(base||10,x);
  return Math.round(this*pow) / pow;
}
Run Code Online (Sandbox Code Playgroud)
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";
Run Code Online (Sandbox Code Playgroud)

.

我不喜欢jsperf那么多,这里有一个链接与使用转换的方法的比较(在其他答案中)和这一个:https :
//jsperf.com/rounding-a-number-2

  • 我认为这是最好的答案.它避免了类型转换.很棒的酱! (12认同)
  • `someNumber = Math.round( 42.008 * 1e2 ) / 1e2;` 的结果不是 `42.01`,而是 `~42.0099999999999980`。原因:数字“42.01”不存在并四舍五入到最接近的现有数字。顺便说一句,通过`toPrecision(18)` 的证明数字用所有相关数字打印出来。 (4认同)
  • @HammerNL 尽管 Sam 坚信,但它实际上并没有做任何事情 :) 这只是一种练习 - 它使 IDE 将此函数识别为“类型 Number”。问题是`+(anyValue)` 总是返回一个数字——例如。`+("45")` 返回 `45`,`+(new Number(42))` 返回 `42`。这有点像强类型函数。如果你养成了习惯,你可以避免很多错误:) (2认同)

Chr*_*ung 115

它返回一个字符串,因为0.1及其功率(用于显示小数部分)在二进制浮点系统中是不可表示的(至少不具有完全准确性).

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

因此(没有十进制浮点或有理数字类型),将其输出为字符串是将其修剪为精确显示所需精度的唯一方法.

  • 至少javascript可以节省我一些手指工作,并将其转换回一个数字... sheesh ... (15认同)
  • @Derek:是的,但是一旦你将它转换回一个数字,你又会遇到同样的不准确问题.:-P JS没有十进制浮点数或有理数. (8认同)
  • 实际上这让我对这个主题进行了一些非常繁重的研究!感谢你的帮助! (6认同)
  • 您的回答有点误导:`toFixed` 是一个格式化函数,其唯一目的是将数字转换为字符串,并使用指定的小数位数对其进行格式化。它返回一个字符串的原因是因为它应该返回一个字符串,如果它被命名为 `toStringFixed`,OP 不会对结果感到惊讶。这里唯一的问题是 OP 期望它像“Math.round”一样工作,而无需咨询 JS 参考。 (2认同)

小智 110

我通过更改此问题解决了这个问题:

someNumber = someNumber.toFixed(2)
Run Code Online (Sandbox Code Playgroud)

......对此:

someNumber = +someNumber.toFixed(2);
Run Code Online (Sandbox Code Playgroud)

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

  • 不,不,不,不,不!**不要**那样做!数字到字符串转换只是圆形它是一个**非常糟糕的做法**!而是`someNumber = Math.round(someNumber*1e2)/ 1e2`!有关更通用的方法,请参阅我的答案. (35认同)
  • `Math.round(someNumber * 1e2) / 1e2` 很容易记住。JavaScript 就是这么有趣 (4认同)
  • @jczaplew因为如果这样做,则32位二进制数将转换为字符串,每个令人讨厌的十进制数**都将使用16位!(通过这种方式将数字存储在UTF-16中并不是您想要的最方便的方法。)然后将字符串转换回32位浮点数。逐位数。(如果我忽略了选择正确的解析算法之前必须完成的所有测试。)考虑到可以使用浮点数上的3个快速操作来做到这一点,都是徒劳的。 (2认同)
  • @m93a 是出于性能原因吗?这实际上对性能有显着影响吗? (2认同)
  • @jczaplew,因为字符串(1)实际上很慢而且(2)理论上不正确. (2认同)

sir*_*lot 23

为什么不用parseFloat

var someNumber = 123.456;
someNumber = parseFloat(someNumber.toFixed(2));
alert(typeof(someNumber));
//alerts number
Run Code Online (Sandbox Code Playgroud)


Joe*_*orn 12

当然它返回一个字符串.如果你想绕数字变量,你可以使用Math.round().toFixed的要点是格式化具有固定小数位数的数字以显示给用户.


Niz*_*zar 12

我通过使用JavaScript的Number()功能将其转换回数字来解决它

var x = 2.2873424;
x = Number(x.toFixed(2));
Run Code Online (Sandbox Code Playgroud)


Pum*_*Pie 6

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

const x1 = 1211.1212121;
const x2 = x1.toFixed(2)*1;
console.log(typeof(x2));
Run Code Online (Sandbox Code Playgroud)


mei*_*sam 5

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

var x = 22.032423;
x = +x.toFixed(2); // x = 22.03
Run Code Online (Sandbox Code Playgroud)