Skip to content

Instantly share code, notes, and snippets.

@r-lyeh-archived
Created November 2, 2015 17:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save r-lyeh-archived/824e3b5426e33844b03e to your computer and use it in GitHub Desktop.
Save r-lyeh-archived/824e3b5426e33844b03e to your computer and use it in GitHub Desktop.
#pragma once
#include <stdint.h>
#if defined(__GNUC__)
# define clz(x) __builtin_clz(x)
# define ctz(x) __builtin_ctz(x)
#elif defined(_MSC_VER)
# include <intrin.h>
uint32_t __inline ctz( uint32_t value ) {
DWORD trailing_zero = 0;
_BitScanForward( &trailing_zero, value );
return trailing_zero;
}
uint32_t __inline clz( uint32_t value ) {
DWORD leading_zero = 0;
_BitScanReverse( &leading_zero, value );
return 31 - leading_zero;
}
#else
static uint32_t ALWAYS_INLINE popcnt( uint32_t x ) {
x -= ((x >> 1) & 0x55555555);
x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
x = (((x >> 4) + x) & 0x0f0f0f0f);
x += (x >> 8);
x += (x >> 16);
return x & 0x0000003f;
}
static uint32_t ALWAYS_INLINE clz( uint32_t x ) {
x |= (x >> 1);
x |= (x >> 2);
x |= (x >> 4);
x |= (x >> 8);
x |= (x >> 16);
return 32 - popcnt(x);
}
static uint32_t ALWAYS_INLINE ctz( uint32_t x ) {
return popcnt((x & -x) - 1);
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment