【问题标题】:Javascript .toFixed() more precise rounding alternative?Javascript .toFixed() 更精确的舍入替代方案?
【发布时间】:2012-09-27 21:42:06
【问题描述】:

对于四舍五入的小数(价格),我使用 .toFixed(2) 已经有一段时间了。但我最近才发现 Javascript 不能“精确”四舍五入。我有点震惊,即使 10.005 也无法正确四舍五入到 10.01。它刚刚四舍五入到 10.00。其他时候它确实正确地四舍五入。我喜欢控制我的代码,所以这对我来说是一个很大的禁忌。

由于我正在计算价格,我认为我需要更准确的 (100%) 数据来舍入 2 位或 3 位小数,也许是 4 位小数。

在javascript中进行基本舍入没有直接的方法,正确的方法吗?

更新:正如 Felix Kling 所建议的,将我的价格处理为美分整数的方法,也有缺点(除了更多代码)?

【问题讨论】:

  • 不要使用浮点值来赚钱。最简单的(imo)解决方案是以美分(或您使用的任何货币)计算价格,并根据您的需要(例如美元和美分)格式化值。这样可以避免舍入错误。
  • 以美分为单位??必须查找那个!
  • 顺便说一句,你确定是 10.005 没有正确舍入,而不是像 10 * 1.0005 这样的东西吗?
  • @alex 确实,这是因为二进制处理,我在某处读过。
  • 其他语言,比如Java,都有Decimal这个数据类型,但是这种东西在JS原生是不存在的。另见:Precise Financial Calculation in JavaScript. What Are the Gotchas?.

标签: javascript jquery


【解决方案1】:

像 10.005 这样的数字不能正确四舍五入的原因是您实际上没有数字 10.005,您只有一个可以使用双精度浮点变量表示的最接近的数字.

您拥有的实际数字可能类似于 10.00499999999276253,它自然会四舍五入为 10.00 而不是 10.01。

要处理货币值,您应该使用可以准确表示该值的数据类型。由于 Javascript 中的数字始终是浮点数,剩下的就是将数字表示为文本,然后编写自己的函数来进行数学运算(或找到已经做过的人)。

【讨论】:

  • 所以使用 BigDecimal 或 BigNumber,而不是将我的价格处理为美分?此外,四舍五入的 10.00499999999276253 仍应为 10.01,因为 0.0049 应变为 0.005,这将导致正确的 0.01。还是我错过了什么?
  • @fishbaitfood:这不是四舍五入的工作原理。如果我舍入0.4445,我希望得到0。根据你的规则,我得到0.445,然后是0.45,然后是0.5,然后是1。多次舍入不是一个好主意。
  • 这是有道理的,但是对于一个 2 位小数的价格数字,它似乎是正确的四舍五入...:/
  • @fishbaitfood — 当舍入到 n 位时,仅考虑前 n + 1 位数字。所以10.00499999999276253 被截断为10.004 然后四舍五入为10.00
  • @fishbaitfood:这不是小费,而是对舍入工作原理的解释。
【解决方案2】:

这应该对你有用,这里有一个小提琴http://jsfiddle.net/5ffyC/1/

function moneyRound(flt){
   var splitStr = flt.toString().split('.'),
      whole = (flt * 100) | 0;

   if (splitStr.length > 1  && splitStr[1].length > 2){
      return splitStr[1][2] > 4? (whole + 1) / 100: whole / 100;
   } else {
      return flt;   
   }
}

【讨论】:

    猜你喜欢
    • 2021-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多