Skip to content

Instantly share code, notes, and snippets.

@airglow923
Last active October 17, 2021 07:49
Show Gist options
  • Save airglow923/fdb4727c2c491e7b1d68c20b7b72a281 to your computer and use it in GitHub Desktop.
Save airglow923/fdb4727c2c491e7b1d68c20b7b72a281 to your computer and use it in GitHub Desktop.
Different ways to get the parity flag in C
/*
* As shown below, this code is not meant for getting the parity of a number;
* rather, it checks the parity flag. The reason is that the parity flag only
* represents whether the least significant byte has odd or even number of set
* bits. So, it should not be used to check the parity of a number in practice
* unless the number is one byte long.
*
* Having said that, an implementation-defined function by Clang and GCC for
* parity computation, __builtin_parity(x), returns 0 if x has even set bits and
* 1 if odd, which is the opposite of the parity flag. That is the reason why
* the code below applies NOT to the return value of __builtin_parity.
*/
#include <stdint.h>
#if defined(__GNUC__) || defined(__clang__)
int
parity1(int64_t n) {
return !__builtin_parity(n);
}
#endif
#if defined(__i386) || defined(_M_IX86)
int
parity2(int64_t n) {
int tmp;
asm("cmp $0, %[n]\n\t"
"lahf\n\t"
"and $1024, %[tmp]"
: [tmp] "=r"(tmp)
: [n] "r"(n));
return tmp;
}
#if defined(__SSE4_2__) || defined(__AVX__) || defined(__POPCNT__)
int
parity3(int64_t n) {
int64_t tmp;
asm("popcntq %[n], %%rax\n\t"
"andq $1, %[tmp]"
: [tmp] "=r"(tmp)
: [n] "r"(n));
return !tmp;
}
#endif
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment