Michal Charemza
Michal Charemza

Reputation: 27012

The index of the first bit

I can see in http://hackage.haskell.org/package/base-4.7.0.0/docs/Data-Bits.html#v:bit how to convert from an Int, n, to a Bit that has the nth bit set, using

bit :: Int -> a

However, how can I do the inverse of this? (Assuming the input Bit just has 1 bit set in it?)

Upvotes: 4

Views: 330

Answers (2)

ephemient
ephemient

Reputation: 204718

Since base-4.8.0.0 there are

countLeadingZeros :: FiniteBits b => b -> Int
countTrailingZeros :: FiniteBits b => b -> Int

Those index the most-significant and least-significant set bits starting from the most-significant and least-significant ends respectively. Subtract from finiteBitSize :: FiniteBits b => b -> Int to count from the other end.

Upvotes: 7

user555045
user555045

Reputation: 64904

popCount $ x-1 does that, effectively by counting the number of trailing zeroes. Subtracting 1 turns the trailing zeroes into ones and resets the only one that should be there.


This is easy to adapt to a more general case without the assumption that only one bit of the input is set: popCount $ complement x .&. (x-1)

The main idea is the same, and the ANDing with the complement of x gets rid of the ones that aren't newly created by the subtraction (which are the only ones that should be counted).

Upvotes: 3

Related Questions