Another one ctfe log2, integer and real versions: [code] module util.ctfelog2;
uint ctfe_ilog2(ulong arg) pure { assert(arg != 0); uint result = 0; while(arg >>= 1) result++; return result; } ulong ctfe_log2(real arg, uint fracBits) pure { import std.math : sqrt, SQRT2; uint intPart = ctfe_ilog2(cast(ulong)arg); ulong result = intPart; if(fracBits == 0 || arg == (1 << intPart)) return result << fracBits; real sq = arg / (1 << intPart); for(uint i = fracBits; i; i--) { if(sq > 2) { result |= 1; sq /= 2; } sq *= sq; result <<= 1; } return result; } real ctfe_log2(real arg) pure { return ctfe_log2(arg, 56) / cast(real)(1UL << 56); } unittest { import std.math : log2, abs; for(real l = 1; l < 256; l += 0.3) { double d1 = ctfe_log2(l); double d2 = log2(l); assert(abs(d1 - d2) < (cast(real)1.0)/(1UL << 48)); } } [/code]