bkaradzic / bx

Base library used across multiple projects

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Better uint32_testpow2

cloudwu opened this issue · comments

I saw your twitter about is_pow_of_2 . There is a better implementation of uint32_testpow2 .

The current version is

uint32_t uint32_testpow2(uint32_t _a) {
	const uint32_t tmp0   = uint32_not(_a);
	const uint32_t tmp1   = uint32_inc(tmp0);
	const uint32_t tmp2   = uint32_and(_a, tmp1);
	const uint32_t tmp3   = uint32_cmpeq(tmp2, _a);
	const uint32_t tmp4   = uint32_cmpneq(_a, 0);
	const uint32_t result = uint32_and(tmp3, tmp4);

	return result;
}

You can use a better version

uint32_t uint32_testpow2(uint32_t _a) {
	const uint32_t tmp0   = uint32_dec(_a);
	const uint32_t tmp1   = uint32_xor(_a, tmp0);
	const uint32_t tmp2   = uint32_srl(tmp1, 1);
	const uint32_t result = uint32_cmpeq(tmp2, tmp0);

	return result;
}

Or, If you don't care _a is zero (return true when _a is 0) , you can also use

uint32_t uint32_testpow2(uint32_t _a) {
	const uint32_t tmp0   = uint32_dec(_a);
	const uint32_t tmp1   = uint32_and(_a, tmp0);
	const uint32_t result = uint32_cmpeq(tmp1, 0);

	return result;
}