【问题标题】:Rounding up to the nearest 0.05 in JavaScript在 JavaScript 中四舍五入到最接近的 0.05
【发布时间】:2012-05-02 12:17:43
【问题描述】:

问题
有谁知道在 JavaScript 中将浮点数舍入到最接近的 0.05 的方法?

示例

BEFORE | AFTER
  2.51 | 2.55
  2.50 | 2.50
  2.56 | 2.60

当前代码

var _ceil = Math.ceil;
Math.ceil = function(number, decimals){
    if (arguments.length == 1)
    return _ceil(number);

    multiplier = Math.pow(10, decimals);
    return _ceil(number * multiplier) / multiplier;
}

然后在其他地方... return (Math.ceil((amount - 0.05), 1) + 0.05).toFixed(2);

这会导致...

BEFORE | AFTER
  2.51 | 2.55
  2.50 | 2.55
  2.56 | 2.65

【问题讨论】:

    标签: javascript rounding


    【解决方案1】:

    乘以 20,然后除以 20:

    (Math.ceil(number*20)/20).toFixed(2)
    

    【讨论】:

    • 完美 - 非常感谢。你能解释为什么你需要这样做吗?
    • 虽然我会考虑这个改变Math.ceil(number*20 - 0.5)/20).toFixed(2)
    • 1 = 20 * 0.05;你乘以 20,这样四舍五入到下一个整数,然后再除以 20 就相当于四舍五入到原来的下一个 0.05。
    • @Sam 考虑两个连续整数之间的浮点数集,例如 0 和 1:0.0、0.5、1.0、...、9.5。有二十种元素。因此,将当前数字乘以 20,取上限,然后除以 20。jsfiddle.net/Wcjau/1。 @Arth:没错,我以为他是要四舍五入到最接近的数字。
    • 啊,这并不是真正四舍五入到最接近的 0.05。应该检查示例!
    【解决方案2】:

    Rob 对我的补充回答:

    (Math.ceil(number*20 - 0.5)/20).toFixed(2)
    

    否则它总是四舍五入到最接近的 0.05。

    ** 更新 **

    很抱歉,有人指出这不是原始海报想要的。

    【讨论】:

    • 我赞成您的评论,但后来我意识到 OP 要求汇总(请参阅问题标题)。
    • 这可能不是 OP 要求的,但这正是我所需要的。您在答案的开头缺少括号。应该是(Math.ceil(_amount*20 - 0.5)/20).toFixed(2)(我修好了)。
    • @usama,我想我实际上更喜欢@marksyzm's answer here for rounding。基本上,两个整数之间有 20 个点,相距 0.05。将值乘以 20 会将数字转换为一个系统,其中每个整数代表这些点之一。使用像ceil/round 这样的整数舍入方法可以让您舍入到下一个/最近的点。最后,将结果除以 20 会将您转换回具有四舍五入值的原始数字系统
    • @usama 附加的- 0.5 基本上将ceil 方法转换为round 方法,这是不必要的混淆.. 最好选择正确的方法!
    • @arth,您对 Rob 答案的原始补充对于银行家四舍五入更为准确,因为我已经在 MBS Online @www9.health.gov.au/mbs/ready_reckoner.cfm?item_num=60 上进行了测试,而您首先需要银行家四舍五入功能@stackoverflow.com/questions/3108986/…
    【解决方案3】:

    我会采用实际除以您要分解的数字的标准,然后将其四舍五入,然后再乘回去。这似乎是一种适当的工作方法,您可以使用任何数量并保持您想要实现的目标的心理形象。

    var val = 26.14,
        factor = 0.05;
    
    val = Math.round(val / factor) * factor;
    

    这将适用于数十、数百或任何数字。如果您专门四舍五入到更高的数字,请使用Math.ceil 而不是Math.round

    另一种专门用于四舍五入到小数点后一位或多位(而不是半位)的方法如下:

    Number(Number(1.5454545).toFixed(1));
    

    它创建一个固定的数字字符串,然后将其转换为一个真实的Number

    【讨论】:

      【解决方案4】:

      我会写一个函数来为你做这件事

      • 将小数点移动两位(乘以 100)
      • 然后将 inflatedNumber 乘以 5 的 mod (%) 并得到余数
      • 从 5 中减去 remainder,这样您就知道您的数字和下一个最接近的 .05 之间的“差距”(ceilGap) 是多少
      • 最后,将您的 inflatedNumber 除以 100,这样它就可以回到原来的浮点数,瞧,您的 num 将四舍五入到最接近的 0.05。

        function calcNearestPointZeroFive(num){
            var inflatedNumber = num*100,
                remainder     = inflatedNumber % 5;
                ceilGap       = 5 - remainder
        
            return (inflatedNumber + ceilGap)/100
        }
        

      如果您想保持 5.50 这样的数字不变,您可以随时添加此检查器:

      if (remainder===0){
          return num
      } else {
          var ceilGap  = 5 - remainder
          return (inflatedNumber + ceilGap)/100
      }
      

      【讨论】:

        【解决方案5】:

        您需要将 -1 向下舍入一半,然后乘以 -1,如下面的示例。

        <script type="text/javascript">
        
          function roundNumber(number, precision, isDown) {
            var factor = Math.pow(10, precision);
            var tempNumber = number * factor;
            var roundedTempNumber = 0;
            if (isDown) {
              tempNumber = -tempNumber;
              roundedTempNumber = Math.round(tempNumber) * -1;
            } else {
              roundedTempNumber = Math.round(tempNumber);
            }
            return roundedTempNumber / factor;
          }
        </script>
        
        <div class="col-sm-12">
          <p>Round number 1.25 down: <script>document.write(roundNumber(1.25, 1, true));</script>
          </p>
          <p>Round number 1.25 up: <script>document.write(roundNumber(1.25, 1, false));</script></p>
        </div>

        【讨论】:

          【解决方案6】:

          我最终在我的项目中成功使用了这个功能:

          roundToNearestFiveCents( number: any ) {
              return parseFloat((Math.round(number / 0.05) * 0.05).toFixed(2));
          }
          

          对于想要简单地将其货币结果四舍五入到最接近的 5 美分并将结果保留为数字的人可能有用,因此如果您进一步对其执行加法,则不会导致字符串连接;正如其他一些答案所指出的那样,也没有不必要的四舍五入。还将其限制为两位小数,这是金融界的惯例。

          【讨论】:

            【解决方案7】:

            我的解决方案和测试:

            let round = function(number, precision = 2, rounding = 0.05) {
              let multiply = 1 / rounding;
            
              return parseFloat((Math.round(number * multiply) / multiply)).toFixed(precision);
            };
            

            https://jsfiddle.net/maciejSzewczyk/7r1tvhdk/40/

            【讨论】:

              【解决方案8】:

              尽管 OP 没有明确说明庄家四舍五入,但四舍五入到最接近的 0.05 美元(5 美分)应该与庄家四舍五入兼容。 Arth 的建议比 Rob W 接受的答案更准确。

              (Math.ceil(number*20 - 0.5)/20).toFixed(2)

              使用银行家舍入,您需要一个基本的银行家舍入函数,如 Gaussian/banker's rounding in JavaScript 建议的那样,我用 TypeScript 重写:

                  static bankerRound(num: number, decimalPlaces?: number) {
                      const d = decimalPlaces || 0;
                      const m = Math.pow(10, d);
                      const n = +(d ? num * m : num).toFixed(8);
                      const i = Math.floor(n), f = n - i;
                      const e = 1e-8;
                      const r = (f > 0.5 - e && f < 0.5 + e) ?
                          ((i % 2 === 0) ? i : i + 1) : Math.round(n);
                      return d ? r / m : r;
                  }
              
                  static roundTo5cents(num: number) {
                      const r = bankerRound(Math.ceil(num * 20 - 0.5) / 20, 2);
                      return r;
                  }
              

              该算法的正确性可以通过MBS Online进行验证,例如: http://www9.health.gov.au/mbs/ready_reckoner.cfm?item_num=60

              【讨论】:

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