Reputation: 487
How can I write a function to return the number of 1 bits corresponding a decimal number? Maybe a square root function? The type should be this:
bits :: Int -> Int
EDIT: SOlved
uns :: Int -> Int
uns 0 = 0
uns 1 = 1
uns x | mod x 2 == 1 = 1 + uns (div x 2)
| otherwise = uns (div x 2)
Upvotes: 2
Views: 916
Reputation: 5674
Use popCount
from Data.Bits
, also known as the Hamming weight of a number. The advantage is that some CPUs have instructions specifically for calculating this, resulting in high performance.
λ> import Data.Bits
λ> :t popCount
popCount :: Bits a => a -> Int
λ> popCount 255
8
λ> popCount 0xa5
4
Upvotes: 5
Reputation: 52057
What about this old trick?
import Data.Bits
countOnes 0 = 0
countOnes x = 1 + countOnes (x .&. (x-1))
It only recurses n times where n is the number of one bits in x.
Of course, if you are going to import Data.Bits
, then you might as well use popCount
as @Cirdec suggested.
Upvotes: 7
Reputation: 52290
I guess Luka has the better version but maybe you struggle a bit with understanding it, so here is what I hinted at (which is the same Luka did only with naive recursion):
bits :: Int -> Int
bits 0 = 0
bits n = let (d,r) = n `divMod` 2
in r + bits d
The idea is to get continous divide by 2 and look at the remainder - if it's 1 then you found a set bit, if not (it has to be 0 then) then there was none.
Upvotes: 3