Round number up to the nearest multiple of 3

前端 未结 12 2019
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-11-28 08:39

Hay, how would i go about rounded a number up the nearest multiple of 3?

ie

25 would return 27
1 would return 3
0 would return 3
6 would return 6


        
相关标签:
12条回答
  • 2020-11-28 09:00

    As mentioned in a comment to the accepted answer, you can just use this:

    Math.ceil(x/3)*3
    

    (Even though it does not return 3 when x is 0, because that was likely a mistake by the OP.)

    Out of the nine answers posted before this one (that have not been deleted or that do not have such a low score that they are not visible to all users), only the ones by Dean Nicholson (excepting the issue with loss of significance) and beauburrier are correct. The accepted answer gives the wrong result for negative numbers and it adds an exception for 0 to account for what was likely a mistake by the OP. Two other answers round a number to the nearest multiple instead of always rounding up, one more gives the wrong result for negative numbers, and three more even give the wrong result for positive numbers.

    0 讨论(0)
  • 2020-11-28 09:00

    Using remainder operator (modulus):

    (n - 1 - (n - 1) % 3) + 3
    
    0 讨论(0)
  • 2020-11-28 09:06

    Building on @Makram's approach, and incorporating @Adam's subsequent comments, I've modified the original Math.prototype example such that it accurately rounds negative numbers in both zero-centric and unbiased systems:

    Number.prototype.mround = function(_mult, _zero) {
    
      var bias = _zero || false;
      var base = Math.abs(this);
      var mult = Math.abs(_mult);
    
      if (bias == true) {
        base = Math.round(base / mult) * _mult;
        base = (this<0)?-base:base ;
      } else { 
        base = Math.round(this / _mult) * _mult;
      }
    
      return parseFloat(base.toFixed(_mult.precision()));
    
    }
    
    Number.prototype.precision = function() {
      if (!isFinite(this)) return 0;
      var a = this, e = 1, p = 0;
      while (Math.round(a * e) / e !== a) { a *= 10; p++; }
      return p;
    }
    

    Examples: (-2).mround(3) returns -3;
    (0).mround(3) returns 0;
    (2).mround(3) returns 3;
    (25.4).mround(3) returns 24;
    (15.12).mround(.1) returns 15.1

    0 讨论(0)
  • 2020-11-28 09:09

    A more general answer that might help somebody with a more general problem: if you want to round numbers to multiples of a fraction, consider using a library. This is a valid use case in GUI where decimals are typed into input and for instance you want to coerce them to multiples of 0.25, 0.2, 0.5 etc. Then the naive approach won't get you far:

    function roundToStep(value, step) {
      return Math.round(value / step) * step;
    }
    
    console.log(roundToStep(1.005, 0.01)); // 1, and should be 1.01
    

    After hours of trying to write up my own function and looking up npm packages, I decided that Decimal.js gets the job done right away. It even has a toNearest method that does exactly that, and you can choose whether to round up, down, or to closer value (default).

    const Decimal = require("decimal.js")
    
    function roundToStep (value, step) {
      return new Decimal(value).toNearest(step).toNumber();
    }
    
    console.log(roundToStep(1.005, 0.01)); // 1.01
    

    RunKit example

    0 讨论(0)
  • 2020-11-28 09:10

    This function will round up to the nearest multiple of whatever factor you provide. It will not round up 0 or numbers which are already multiples.

    round_up = function(x,factor){ return x - (x%factor) + (x%factor>0 && factor);}
    
    round_up(25,3)
    27
    round up(1,3)
    3
    round_up(0,3)
    0
    round_up(6,3)
    6
    

    The behavior for 0 is not what you asked for, but seems more consistent and useful this way. If you did want to round up 0 though, the following function would do that:

    round_up = function(x,factor){ return x - (x%factor) + ( (x%factor>0 || x==0) && factor);}
    
    round_up(25,3)
    27
    round up(1,3)
    3
    round_up(0,3)
    3
    round_up(6,3)
    6
    
    0 讨论(0)
  • 2020-11-28 09:14

    (n - n mod 3)+3

    0 讨论(0)
提交回复
热议问题