toFixed()函数背后的规则是什么

时间:2019-03-29 21:04:19

标签: javascript function tofixed

我正在测试javascript的toFixed()方法。结果如下。

(49.175).toFixed(2) => "49.17"
(49.775).toFixed(2) => "49.77"
(49.185).toFixed(2) => "49.19"
(49.785).toFixed(2) => "49.78"

(49.1175).toFixed(3) => "49.117"
(49.1775).toFixed(3) => "49.178"
(49.1185).toFixed(3) => "49.118"
(49.1785).toFixed(3) => "49.178"

我在chrome浏览器上进行了此测试,结果令我感到惊讶。我听不懂逻辑。它既不适合“从零舍入”也不适合“舍入到偶数”。 “ toFixed()”函数的背后规则是什么?

3 个答案:

答案 0 :(得分:2)

  

关于固定

返回一个包含此Number值的字符串,该值以十进制定点表示法表示,并在小数点后加小数位数。如果未定义fractionDigits,则假定为0。具体来说,请执行以下步骤:

算法Number.prototype.toFixed (fractionDigits)https://www.ecma-international.org/ecma-262/5.1/#sec-15.7.4.5

  • toFixed方法的length属性为1。

    • 如果使用多个参数调用toFixed方法,则该行为是不确定的(请参见第15节)。

对于小数位数小于0或大于20的值,允许实现扩展toFixed的行为。在这种情况下,toFixed不一定会为此类值引发RangeError。

注意对于某些值,toFixed的输出可能比toString更精确,因为toString仅打印足够的有效数字以区分数字与相邻数字值。

  

JS解决方法

function fix(n, p) {
  return (+(Math.round(+(n + 'e' + p)) + 'e' + -p)).toFixed(p);
}
let exampleA = fix(49.1175, 3);
let exampleB = fix(49.1775, 3);
let exampleC = fix(49.775, 2);
const random = Math.random();
console.log(exampleA);
console.log(exampleB);
console.log(exampleC);
console.log('Before:', random, 'After Custom =>', fix(random, 3), 'Default:', random.toFixed(3));
// 49.118
// 49.178
// 49.78

  

需要精度

我建议只是将set precision C ++ 移植到Node.JS模块。

  • 您可以在 Node.JS 中简单地装配并使用child_process来调用带有参数的 C ++ 程序,并让 C ++ 运行一个函数来转换值并将其输出到控制台。

答案 1 :(得分:1)

问题是,您输入的号码不存在!扫描时,将它们(二进制)四舍五入到最接近的可能数字/现有数字。 toPrecision(18)更精确地显示了扫描后的数字:

(49.175).toPrecision(18); // "49.1749999999999972" => "49.17"
(49.775).toPrecision(18); // "49.7749999999999986" => "49.77"
(49.185).toPrecision(18); // "49.1850000000000023" => "49.19"
(49.785).toPrecision(18); // "49.7849999999999966" => "49.78"

因此,该数字四舍五入两次:首先是扫描,然后是toFixed()

答案 2 :(得分:0)

来自MDN

  

toFixed()返回numObj的字符串表示形式,该字符串表示形式不使用指数表示法,并且精确到小数点后一位数字。如有必要,数字取整,并且如有必要,小数部分用零填充,以使其具有指定的长度。如果numObj大于或等于1e + 21,则此方法仅调用Number.prototype.toString()并以指数表示法返回字符串。

稍后您可以阅读:

  

警告::浮点数不能精确表示所有二进制的小数,这可能导致意外的结果,例如0.1 + 0.2 === 0.3返回false。

以上警告与舍入逻辑(可能是数字上的算术运算)结合在一起,将解释您在舍入过程中尝试的不同行为(您可以阅读here)。