简体   繁体   中英

What is the best way to determine if a given number is a power of two?

I need to return true if the n is a power of two and false otherwise. It should go something like:

function PowerOfTwo(n){
  //code here
}

This is the way I currently do it:

function isPowerOfTwo(n){
  var x = Math.pow(2, Math.round(Math.log(n) / Math.log(2)));
  return x;
}

Are there any more effective ways?

You can actually use ECMAScript5 Math.log :

function powerOfTwo(x) {
    return (Math.log(x)/Math.log(2)) % 1 === 0;
}

Remember, in math, to get a logarithm with an arbitrary base, you can just divide log 10 of the operand ( x in this case) by log 10 of the base. And then to see if the number is a regular integer (and not a floating point), just check if the remainder is 0 by using the modulus % operator.

In ECMAScript6 you can do something like this:

function powerOfTwo(x) {
    return Math.log2(x) % 1 === 0;
}

See the MDN docs for Math.log2 .

Source: Bit twiddling Hacks ,

function powerOf2(v) {
    return v && !(v & (v - 1));
}

You just bitwise AND the previous number with the current number. If the result is falsy, then it is a power of 2.

The explanation is in this answer .

Note:

  • This will not be 100% true for programming, mathematical, [also read 'interviewing']. Some edge cases not handled by this are decimals (0.1, 0.2, 0.8…) or zero values (0, 0.0, …)

Using bitwise operators, this is by far the best way in terms of efficiency and cleanliness of your code:

function PowerofTwo(n){
    return ((x != 0) && !(x & (x - 1)));
}

what it does is checks the bits that make up the number, ie 8 looks like this:

1 0 0 0

x-1 or 7 in this case looks like this

0 1 1 1

when the bitwise operator & is used it invokes an && on each bit of the number (thus 1 & 1 = 1 , 1 & 0 = 0 , 0 & 1 = 0 , 0 & 0 = 1 ):

 1 0 0 0
-0 1 1 1
=========
 0 0 0 0

since the number turns into an exact 0 (or false when evaluted as a boolean) using the ! flag will return the correct answer

if you were to do this with a number like 7 it would look like this:

 0 1 1 1
-0 1 1 0
=========
 1 1 1 0

returning a number greater than zero causing the ! flag to take over and give the correct answer.

A number is a power of 2 if and only if log base 2 of that number is whole. The function below computes whether or not that is true:

function powerOfTwo(n){
    // Compute log base 2 of n using a quotient of natural logs
    var log_n = Math.log(n)/Math.log(2);
    // Round off any decimal component
    var log_n_floor = Math.floor(log_n);
    // The function returns true if and only if log_n is a whole number
    return log_n - log_n_floor == 0; 
}

Making use of ES6's Math.clz32(n) to count leading zeros of a 32-bit integer from 1 to 2³² - 1:

function isPowerOf2(n) {
  return Math.clz32(n) < Math.clz32(n - 1);
}

 /** * @param {number} n * @return {boolean} */ const isPowerOfTwo = function(n) { if(n == 0) return false; while(n % 2 == 0){ n = n/2 } return n === 1 };

function PowerOfTwo(n){
  // Exercise for reader: confirm that n is an integer
  return (n !== 0) && (n & (n - 1)) === 0;
}

without using libraries

so you need to create an inner loop using while

it should start with 1 keep multiplying it with 2 until i,j,k or whatever is greater than the current number(array) so it will have to do 2 4 6 8 10 12 14 16 18 until it is greater than the number then it will go to the outer loop then repeat again

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM