我正在测试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()”函数的背后规则是什么?
答案 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。
对于小数位数小于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模块。
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)