20

问题
有谁知道在 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
4

8 回答 8

43

乘以 20,然后除以 20:

(Math.ceil(number*20)/20).toFixed(2)
于 2012-05-02T12:19:28.883 回答
17

Rob 对我的补充回答:

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

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

** 更新 **

对不起,有人指出这不是原始海报想要的。

于 2012-05-02T12:28:05.753 回答
11

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

var val = 26.14,
    factor = 0.05;

val = Math.round(val / factor) * factor;

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

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

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

它创建一个固定数字字符串,然后将其变成一个实数Number

于 2014-01-27T14:24:21.147 回答
3

我会写一个函数来为你做

  • 将小数点移动两位(乘以 100)
  • 然后 mod ( %)inflatedNumber乘以 5 并得到余数
  • 从 5 中减去,remainder这样你就知道ceilGap你的数字和下一个最接近的 0.05 之间的“差距”( )是多少
  • 最后,将您inflatedNumber的数字除以 100,使其回到原来的浮点数,瞧,您的数字将四舍五入到最接近的 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
}
于 2015-07-28T17:15:19.313 回答
1

您需要将 -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>

于 2017-10-25T12:51:13.553 回答
1

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

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

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

于 2018-08-15T11:44:13.373 回答
1

我的解决方案和测试:

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/

于 2019-10-05T08:58:04.110 回答
0

尽管 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

于 2021-01-18T05:03:59.963 回答