开发者

refactor this basic code that determines if number is in tens, hundreds, thousands etc

 if (n<100) {
     x = 10;
 } else if (n<1000) {
     x = 100;
 } else if (n<100开发者_StackOverflow社区00) {
     x = 1000;
 } else if (n....

etc. etc.

Is there a nice concise, scalable method for this type of problem? My brain has decided to stop working.


var x = Math.pow( 10, Math.floor( Math.log(n) / Math.log(10) ) );

This one might be preferable, because it's available as a constant so it doesn't need to be calculated each time:

var x = Math.pow( 10, Math.floor( Math.log(n) / Math.LN10 ) );

It basically comes down to rounding down logarithmically.


Edit: Because a combination of log and / often tends to result in errors, it might be a good idea to round the quotient as well (currently, Math.log(1000) / Math.LN10 === 2.9999999999999996).

var x = Math.pow( 10, Math.floor( Math.round( Math.log(1000) / Math.LN10 * 1e10 ) / 1e10 ) );

This rounding might result in new errors, but for 'normal' inputs the answer is now more often correct.


Here's a solution using recursion:

function find_place( x, n ) {
    return x >= 10 ? find_place( x/10, ++n || 1  ) : Math.pow( 10, n || 0 );
}

find_place( 3 );    // 1
find_place( 33 );   // 10
find_place( 333 );  // 100

EDIT: Fixed to use x >= 10 instead of x > 10.


Here's a version that removes the need for Math.pow().

function find_place(x, n) {
    return x >= 10 ? find_place(x / 10, (n || 1) * 10) : n || 1;
}

Or run effectively the same code in a loop instead of a recursive function to speed it up a bit.

var x = 12345,
    n = 1;   // n will hold the result
while (x >= 10) {
  x /= 10;
  n *= 10;
}


One cleanup is to make this its own method, with return values. That way you avoid all the else if's

...
if (n < 100) return 10;
if (n < 1000) return 100;
if (n < 10000) return 1000; 
...

This isn't as good, as general, as clean as using the pow() function @pimvdb suggested, but it is a good more general way to clean up code with an "else-iffy" feel like the one presented.


You could try

x=Math.pow(10, Math.floor(Math.log(n)/Math.LN10));


I needed to do something similar and came up with the following:

x = Math.pow( 10, ( '' + n ).length - 1 );

And some test cases, jsFiddle:

n = 33;   // x = 10
n = 213;  // x = 100
n = 1776; // x = 1000

Don't know if the performance is any better than all the log stuff, and this assumes n is an integer.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜