Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test if a number is a power of 2?

I want to do a simple test for if a number is a power of 2 in Haskell for a case guard I am making.

The purpose is to determine whether a number is even (and not a power of 2), whether a number is odd, or whether a number is to the power of 2.

I want to do something like:

function n
  | n `mod` 2 == 1 = 1
  | if n is to the power of 2 = 2
  | otherwise = 0

I have looked at some threads but they all say to use the bitwise operator:

(n & (n - 1)) == 0

However it says

Not in scope: ‘&’

when I try to do so, so am not sure if that is allowed in Haskell.

like image 592
DoubleRainbowZ Avatar asked Oct 21 '19 07:10

DoubleRainbowZ


People also ask

How do you find out if a number is a power of 2?

To check if a given number is a power of 2, we can continuously divide the number by 2, on the condition that the given number is even. After the last possible division, if the value of the number is equal to 1, it is a power of 2. Otherwise, it is not.

How do you check if a number is a power of 2 using bit?

If (x & (x-1)) is zero then the number is power of 2. For example, let x be 8 ( 1000 in binary); then x-1 = 7 ( 0111 ). This outputs the bit is power of 2 .

What makes a number a power of 2?

A power of two is a number of the form 2n where n is an integer, that is, the result of exponentiation with number two as the base and integer n as the exponent.


1 Answers

Haskell has bitwise operations, but these have a slightly different name. Indeed, you can make a bitwise AND with the (.&.) :: Bits a => a -> a -> a function.

You thus can make such check with:

import Data.Bits(Bits, (.&.))

isPower2 :: (Bits i, Integral i) => i -> Bool
isPower2 n = n .&. (n-1) == 0

Note that your proposed solution will include zero as a power of two as well. Indeed, if we evaluate the first 1'000 numbers, we get:

Prelude Data.Bits> filter isPower2 [0 .. 1000]
[0,1,2,4,8,16,32,64,128,256,512]
like image 54
Willem Van Onsem Avatar answered Sep 27 '22 20:09

Willem Van Onsem