开发者

Math.ceil to nearest five at position 1

开发者 https://www.devze.com 2023-04-04 09:28 出处:网络
Okay.... I have a lot of uncontrolled numbers i want to round: 51255 -> 55000 25 -> 25开发者_运维百科

Okay....

I have a lot of uncontrolled numbers i want to round:

51255 -> 55000
25 -> 25开发者_运维百科
9214 -> 9500
13135 -> 15000
25123 -> 30000

I have tried modifying the numbers as string and counting length....

But is there a simple way using some Math function maybe?


Here's my late answer. Uses no Math methods.

function toN5( x ) {
    var i = 5;
    while( x >= 100 ) {x/=10; i*=10;}
    return ((~~(x/5))+(x%5?1:0)) * i;
}

DEMO: http://jsbin.com/ujamoj/edit#javascript,live

   [51255, 24, 25, 26, 9214, 13135, 25123, 1, 9, 0].map( toN5 );

// [55000, 25, 25, 30, 9500, 15000, 30000, 5, 10, 0]

Or this is perhaps a bit cleaner:

function toN5( x ) {
    var i = 1;
    while( x >= 100 ) {x/=10; i*=10;}
    return (x + (5-((x%5)||5))) * i;
}

DEMO: http://jsbin.com/idowan/edit#javascript,live

To break it down:

function toN5( x ) {
   //       v---we're going to reduce x to the tens place, and for each place
   //       v       reduction, we'll multiply i * 10 to restore x later.
    var i = 1;

   // as long as x >= 100, divide x by 10, and multiply i by 10.
    while( x >= 100 ) {x/=10; i*=10;}

   // Now round up to the next 5 by adding to x the difference between 5 and
   //    the remainder of x/5 (or if the remainder was 0, we substitute 5
   //    for the remainder, so it is (x + (5 - 5)), which of course equals x).

   // So then since we are now in either the tens or ones place, and we've
   //    rounded to the next 5 (or stayed the same), we multiply by i to restore
   //    x to its original place.
    return (x + (5-((x%5)||5))) * i;
}

Or to avoid logical operators, and just use arithmetic operators, we could do:

return (x + ((5-(x%5))%5)) * i;

And to spread it out a bit:

function toN5( x ) {
    var i = 1;
    while( x >= 100 ) {
        x/=10; 
        i*=10;
    }
    var remainder = x % 5;
    var distance_to_5 = (5 - remainder) % 5;
    return (x + distance_to_5) * i;
}


var numbers = [51255, 25, 9214, 13135, 25123, 3, 6];

function weird_round(a) {
    var len = a.toString().length;
    var div = len == 1 ? 1 : Math.pow(10, len - 2);
    return Math.ceil(a / 5 / div) * div * 5;
}

alert(numbers.map(weird_round));

Also updated for numbers below 10. Won't work properly for negative numbers either, just mention if you need this.

DEMO


I'm not sure why, but I thought it would be fun with regular expressions:

    var result = +(number.toString().replace(/([1-9])([0-9])(.+)/, function() {
        return Math.ceil(+(arguments[1] + '.' + arguments[2])) * 10 - (+arguments[2] < 5?5:0) + arguments[3].replace(/./g, '0');
    }));

Working Demo


    with(Math) {
        var exp = floor(log(number)/log(10)) - 1;
        exp = max(exp,0);
        var n = number/pow(10,exp);
        var n2 = ceil(n/5) * 5;
        var result = n2 * pow(10,exp);
    }

http://jsfiddle.net/NvvGf/4/

Caveat: only works for the natural numbers.


function round(number) {
   var numberStr = number + "",
       max,
       i;

   if (numberStr[1] > '4') {
       numberStr[0] = parseInt(numberStr[0]) + 1;
       numberStr[1] = '0';
   } else {
       numberStr[1] = '5';
   }

   for (i = 2; max = numberStr.length; i < max; i += 1) {
      numberStr += '0';
   }

   return parseInt(numberStr);
}


Strange coincidence, I wrote something really similar not so long ago!

function iSuckAtNames(n) {
    var n = n.toString(), len = n.length, res;

    //Check the second number. if it's less than a 5, round down,
    //If it's more/equal, round up

    //Either way, we'll need to use this:
    var res = parseFloat(n[0]) * Math.pow(10, len - 1); //e.g. 5 * 10^4 = 50000
    if (n[1] <= 5) {
        //we need to add a 5 right before the end!
        res += 5 * Math.pow(10, len - 2);
    }
    else {
        //We need another number of that size
        res += Math.pow(10, len - 1);
    }
    return res;
}
0

精彩评论

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