开发者

Javascript intelligent rounding

开发者 https://www.devze.com 2023-04-06 08:27 出处:网络
I currently need to round numbers up to the开发者_运维百科ir nearest major number. (Not sure what the right term is here)

I currently need to round numbers up to the开发者_运维百科ir nearest major number. (Not sure what the right term is here)

But see an example of what I'm trying to achieve

IE:

 13 // 20
 349 // 400
 5645 // 6000
 9892 // 10000
 13988 // 20000
 93456 // 100000
 231516 // 300000

etc. etc.

I have implemented a way of doing this but its so painful and only handles numbers up to a million and if I want it to go higher I need to add more if statements (yeah see how i implmented it :P im not very proud, but brain is stuck)

There must be something out there already but google is not helping me very much probably due to me not knowing the correct term for the kind of rounding i want to do


<script type="text/javascript">
    function intelliRound(num) {
        var len=(num+'').length;
        var fac=Math.pow(10,len-1);
        return Math.ceil(num/fac)*fac;
    }
    alert(intelliRound(13));
    alert(intelliRound(349));
    alert(intelliRound(5645));
    // ...
</script>

See http://jsfiddle.net/fCLjp/


One way;

var a = [13, // 20
 349, // 400
 5645, // 6000
 9892, // 10000
 13988, // 20000
 93456, // 100000
 231516 // 300000
]

for (var i in a) {
    var num = a[i];
    var scale = Math.pow(10, Math.floor(Math.log(num) / Math.LN10));
    print([ num, Math.ceil(num / scale) * scale ])
}

13,20
349,400
5645,6000
9892,10000
13988,20000
93456,100000
231516,300000


The answer from @rabudde works well, but for those that need to handle negative numbers, here's an updated version:

function intelliRound(num) {
     var len = (num + '').length;
     var result = 0;
     if (num < 0) {
         var fac = Math.pow(10, len - 2); 
         result = Math.floor(num / fac) * fac;
     }
     else {
        var fac = Math.pow(10, len - 1);
        result = Math.ceil(num / fac) * fac;
     }
     return result;
}
alert(intelliRound(13));
alert(intelliRound(349));
alert(intelliRound(5645));
            
alert(intelliRound(-13));
alert(intelliRound(-349));
alert(intelliRound(-5645));


you can use Math.ceil function, as described here:

javascript - ceiling of a dollar amount

to get your numbers right you'll have to divide them by 10 (if they have 2 digits), 100 (if they have 3 digits), and so on...


The intelliRound function from the other answers works well, but break with negative numbers. Here I have extended these solutions to support decimals (e.g. 0.123, -0.987) and non-numbers:

/**
 * Function that returns the floor/ceil of a number, to an appropriate magnitude
 * @param {number} num - the number you want to round
 *
 * e.g.
 * magnitudeRound(0.13) => 1
 * magnitudeRound(13) => 20
 * magnitudeRound(349) => 400
 * magnitudeRound(9645) => 10000
 * magnitudeRound(-3645) => -4000
 * magnitudeRound(-149) => -200
 */

function magnitudeRound(num) {
  const isValidNumber = typeof num === 'number' && !Number.isNaN(num);
  const result = 0;

  if (!isValidNumber || num === 0) return result;
  const abs = Math.abs(num);
  const sign = Math.sign(num);

  if (abs > 0 && abs <= 1) return 1 * sign; // percentages on a scale -1 to 1
  if (abs > 1 && abs <= 10) return 10 * sign;
  const zeroes = `${Math.round(abs)}`.length - 1; // e.g 123 => 2, 4567 => 3
  const exponent = 10 ** zeroes; // math floor and ceil only work on integer
  const roundingDirection = sign < 0 ? 'floor' : 'ceil';

  return Math[roundingDirection](num / exponent) * exponent;
}

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号