javascript - 0.5时向上或向下舍入

标签 javascript math rounding precision

我对 Javascript 在达到 0.5 时舍入数字的方式有疑问。 我正在编写征税计算器,我注意到结果中存在 0.1c 的差异。

问题是他们的结果是 21480.705,我的应用程序将其转换为 21480.71,而关税显示为 21480.70

这是我在 Javascript 中看到的:

(21480.105).toFixed(2)
"21480.10"
(21480.205).toFixed(2)
"21480.21"
(21480.305).toFixed(2)
"21480.31"
(21480.405).toFixed(2)
"21480.40"
(21480.505).toFixed(2)
"21480.51"
(21480.605).toFixed(2)
"21480.60"
(21480.705).toFixed(2)
"21480.71"
(21480.805).toFixed(2)
"21480.81"
(21480.905).toFixed(2)
"21480.90"

问题:

  • 这种不稳定的路由到底是怎么回事?
  • 获得“四舍五入”结果(达到 0.5 时)的最快最简单方法是什么?

最佳答案

因此,正如其他一些人已经解释的那样,“不稳定”舍入的原因是浮点精度问题。您可以使用 JavaScript 数字的 toExponential() 方法对此进行调查。

(21480.905).toExponential(20)
#>"2.14809049999999988358e+4"
(21480.805).toExponential(20)
#>"2.14808050000000002910e+4"

正如您在此处看到的那样,21480.905 获得了比 21480.905 稍小的 double 表示,而 21480.805 获得了稍大的 double 表示比原来的值(value)。由于 toFixed() 方法使用双重表示,并且不知道您的原始预期值,因此它会尽其所能并且应该使用它所拥有的信息。

解决此问题的一种方法是通过乘法将小数点移动到您需要的小数位数,然后使用标准 Math.round(),然后再次将小数点移回,通过除法或乘以倒数。最后我们调用 toFixed() 方法来确保输出值被正确地补零。

var x1 = 21480.905;
var x2 = -21480.705;

function round_up(x,nd)
{
  var rup=Math.pow(10,nd);
  var rdwn=Math.pow(10,-nd); // Or you can just use 1/rup
  return (Math.round(x*rup)*rdwn).toFixed(nd)
}
function round_down(x,nd)
{
  var rup=Math.pow(10,nd);
  var rdwn=Math.pow(10,-nd); 
  return (Math.round(x*-rup)*-rdwn).toFixed(nd)
}

function round_tozero(x,nd)
{
   return x>0?round_down(x,nd):round_up(x,nd) 
}



console.log(x1,'up',round_up(x1,2));
console.log(x1,'down',round_down(x1,2));
console.log(x1,'to0',round_tozero(x1,2));

console.log(x2,'up',round_up(x2,2));
console.log(x2,'down',round_down(x2,2));
console.log(x2,'to0',round_tozero(x2,2));

最后: 遇到这样的问题通常是坐下来仔细考虑一下您是否真的使用了正确的数据类型来解决您的问题的好时机。由于浮点错误会随着迭代计算而累积,并且由于人们有时对货币神奇地消失/出现在 CPU 中异常敏感,也许您最好将货币计数器保持在整数“美分”(或其他一些经过深思熟虑的结构)而不是浮点“美元”。

关于javascript - 0.5时向上或向下舍入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55096050/

相关文章:

javascript - NodeJS - 直接流式传输到 Azure 数据湖

javascript - 去抖不起作用

java - 如何使用Math.pow计算bmi

java - Java中相同的(int)double向上和向下取整

javascript - 使用 D3 的缩放功能在 [-1, 1] 范围内缩放值

javascript - 在 Javascript 中,将小数加到数字上,将其乘以 10

javascript - 随着时间的推移加速

c++ - 四舍五入的值(value)

objective-c - 将 Objective-C float 四舍五入到最接近的 .05

javascript - IE8 中的 FB 分享按钮 Javascript 错误