2

我正在测试 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()' 函数背后的规则是什么?

4

3 回答 3

3

关于到固定

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

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

  • toFixed 方法的长度属性为 1。

    • 如果使用多个参数调用 toFixed 方法,则行为未定义(参见第 15 节)。

对于小于 0 或大于 20 的 fractionDigits 的值,允许实现扩展 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 precisionC++移植到 Node.JS 模块。

  • child_process您可以简单地在Node.JS中安装并使用 a来调用带有参数的C++程序,并让C++运行一个函数来将值转换并输出到控制台。
于 2019-03-29T21:12:48.987 回答
3

问题是,您输入的数字不存在!在扫描时,它们(二进制)四舍五入到最接近的可能/现有数字。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"

所以这个数字被四舍五入了 2 次:首先是扫描,然后是toFixed()

于 2019-04-04T06:54:19.210 回答
0

来自MDN

toFixed()返回不使用指数表示法的字符串表示形式numObj,并且在小数点后具有精确的数字。必要时对数字进行四舍五入,必要时用零填充小数部分,使其具有指定的长度。如果numObj大于或等于 1e+21,则此方法简单地调用Number.prototype.toString()并返回一个以指数表示的字符串。

稍后您可以阅读:

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

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

于 2019-03-29T21:13:03.110 回答