
#define for if(false){}else for

int base2log(const unsigned int number, const unsigned int number_mantissa_size, const unsigned int log_mantissa_size)
{
	// zero will mess up the algorithm below
	if ( number == 0u ) return 0u;

	// cpower is chosen so that ((2^(cpower+1))-1)^2 will fit in an unsigned int
	static const unsigned int cpower = ((sizeof(unsigned int)*8u)/2u)-1u;
	static const unsigned int one = 1u << cpower;
	static const unsigned int two = 2u << cpower;

	int l = cpower - number_mantissa_size; // number is actually number/(2^number_mantissa_size), so number_mantissa_size is subtracted from the log (it is done at the beginning to circumvent having to shift number_mantissa_size)
	unsigned int n = number;

	// make sure one <= n < two (and administrer any shifts in l, l becomes floor(log(number)))
	while(n < one)
	{
		n <<= 1u;
		--l;
	}
	while(n >= two)
	{
		n >>= 1u;
		++l;
	}

	// now calculate some binary digits
	for(unsigned int mantissa_bit = 0u; mantissa_bit < log_mantissa_size; ++mantissa_bit)
	{
		l <<= 1u;		// make room for an extra bit (shifting a negative signed integer works perfectly!)
		n *= n;			// n_new = n_old^2 = (2^0.yxxx)^2 = 2^y.xxx
		n >>= cpower;	// normalize n to keep n from getting too large
		if ( n >= two )
		{	// apparently y (see the comment behind n *= n) was 1
			l |= 1u;	// set the LSB to 1
			n >>= 1u;	// divide by two, subtracting 1 from 1.xxx (n/2 = (2^-1)(2^1.xxx) = 2^0.xxx) to prepare for the next step
		}
	}

	return l;
}
