3

Given an int variable, I would like to check if the number of '1' in its binary representation is even or odd. It can be made with xor operations like

int n; 
int s = 0;
for(;n;n>>=1)
    s ^= (n&1);

There's some better way to do so in C++?

Note: I'm not asking for the number of '1's, but for its parity, so I thought there could be some better code than mine.

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Exodd
  • 221
  • 1
  • 9

2 Answers2

6
uint32_t v = somevalue;
v ^= v >> 1;
v ^= v >> 2;
v = (v & 0x11111111U) * 0x11111111U;
bool parity = (v >> 28) & 1;  

From https://graphics.stanford.edu/~seander/bithacks.html
It has a 64bit variant too.

For clarification, with "parity" I don't mean if the number is even or odd mathematically, but if the count of 1 bits in it's binary representation is even or odd; like described in https://en.wikipedia.org/wiki/Parity_bit. With the maths meaning, the code in the question makes no sense, so I assumed OP means the same. The statement

I'm not asking for the number of '1's, but for its parity

then means that he/she just wants to know if the 1 count is even or odd,
but not the exact number of 1's.

deviantfan
  • 11,268
  • 3
  • 32
  • 49
  • 1
    According to your link "The following method computes the parity of the 32-bit value"....it's not the parity of the number of "1" in the binary representation of the number....is it? – jpo38 Oct 11 '15 at 14:06
  • @jpo38 Quote from the question: `I would like to check if the number of '1' in its binary representation is even or odd.`. That *is* the parity of a value (not the parity of the popcount) – deviantfan Oct 11 '15 at 14:07
  • For me `parity of a value` is to know if this value is odd or even....not if it's binary representation has a odd or even number of `1`...but I'm most likely wrong (or I misunderstand the terms, english is not my mother tongue) because your solution works....;-) – jpo38 Oct 11 '15 at 14:18
  • @jpo38 `A parity bit, or check bit is a bit ... that indicates whether the number of bits in the string with the value one is even or odd.` from https://en.wikipedia.org/wiki/Parity_bit (and I'm not a native English speaker too) – deviantfan Oct 11 '15 at 14:20
  • Thanks for the clarification, I learnt something....this deserves a upvote ;-) – jpo38 Oct 11 '15 at 14:23
  • Why is it better then continue to apply v ^= v >>4, >>8, >>16 ? – Exodd Oct 11 '15 at 14:28
  • @Exodd I don't know what you meant. – deviantfan Oct 11 '15 at 14:36
  • v ^= v >> 1; v ^= v >> 2; v ^= v >> 4; v ^= v >> 8; v ^= v >> 16; bool parity = v&1; – Exodd Oct 11 '15 at 14:37
  • @Exodd While benchmarks are never the same, your code is likely to be slower. – deviantfan Oct 11 '15 at 14:57
1

If you are really after speed, you can tabulate the number of bits (or just its parity) for all byte values 0..255. Then mapping a union on the variable or using shifts/masks, accumulate for the four bytes.

Even faster and more paranoid, tabulate for all short values 0..65535.