在JavaScript中舍入到最接近的0.05

时间:2012-05-02 12:17:43

标签: javascript rounding

问题
有没有人知道在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

8 个答案:

答案 0 :(得分:28)

乘以20,然后除以20:

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

答案 1 :(得分:8)

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

var val = 26.14,
    factor = 0.05;

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

这将适用于数十,数百或任何数字。如果您特别舍入到较高的数字,请使用Math.ceil代替Math.round

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

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

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

答案 2 :(得分:7)

Rob的回答是我的补充:

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

否则它总是向上舍入到最接近的0.05。

**更新**

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

答案 3 :(得分:2)

I would write a function that does it for you by

  • move the decimal over two places (multiply by 100)
  • then mod (%) that inflatedNumber by 5 and get the remainder
  • subtract the remainder from 5 so that you know what the 'gap'(ceilGap) is between your number and the next closest .05
  • finally, divide your inflatedNumber by 100 so that it goes back to your original float, and voila, your num will be rounded up to the nearest .05.

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

If you want to leave numbers like 5.50 untouched you can always add this checker:

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

答案 4 :(得分:0)

你需要把-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>

答案 5 :(得分:0)

我最终在项目中成功使用了此功能:

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

对于那些希望简单地将其货币结果四舍五入至最接近的5美分,使结果保持数字的人可能会有用,因此,如果对它进一步执行加法运算,则不会导致字符串串联;也不必像其他一些答案所指出的那样不必要地四舍五入。还将其限制为两位小数,这是金融惯例。

答案 6 :(得分:0)

我的解决方案和测试:

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/

答案 7 :(得分: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