//#define FAILPOINT using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Runtime.InteropServices; using System.Runtime.ConstrainedExecution; using System.Configuration; using System.Diagnostics; using System.Reflection; using System.IO; using System.Security; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using alib; using alib.Array; using alib.Bits; using alib.Collections; using alib.Debugging; using alib.Enumerable; namespace ConsoleApp5 { [SuppressUnmanagedCodeSecurity] static class candidates { static candidates() { msb_tab_7 = setup_7(); msb_tab_8 = setup_8(); msb_tab_15 = setup_15(); msb_tab_16 = setup_16(); //msb_tab_nyb = setup_nyb(); } [DebuggerBrowsable(DebuggerBrowsableState.Never)] readonly static byte[] msb_tab_7, msb_tab_8, msb_tab_15, msb_tab_16; static byte[] setup_16() { int i, c; byte n; var p = new byte[0x10000]; p[0] = 0xFF; for (n = 0; n < 16; n++) for (c = 1 << n, i = 0; i < c; i++) p[c + i] = n; return p; } //static byte[] setup_nyb() //{ // int i, c, j; // byte n; // var p = new byte[0x4000]; // j = 0; // for (n = 0, c = 1; n < 16; c <<= 1, n++) // for (i = 0; i < c; i += 2) // { // p[j++] = n; // } // return p; //} //{ // 0x00, 0x01, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, // 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, // 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, // 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, // 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, // 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, // 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, // 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, // 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, // 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, // 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, // 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, // 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, // 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, // 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, //}; static byte[] setup_7() { int i, c; byte n; var p = new byte[0x80]; for (n = 0; n < 8; n++) for (c = (1 << n) >> 1, i = 0; i < c; i++) p[c + i] = n; return p; } static byte[] setup_8() { int i, c; byte n; var p = new byte[0x100]; p[0] = 0xFF; for (n = 0; n < 8; n++) for (c = 1 << n, i = 0; i < c; i++) p[c + i] = n; return p; } static byte[] setup_15() { int i, c; byte n; var p = new byte[0x8000]; for (n = 0; n < 16; n++) for (c = (1 << n) >> 1, i = 0; i < c; i++) p[c + i] = n; return p; } //static byte[] setup_nyb() //{ // int i, c, j; // byte n; // var p = new byte[0x4000]; // j = 0; // for (n = 0, c = 1; n < 16; c <<= 1, n++) // for (i = 0; i < c; i += 2) // { // p[j++] = n; // } // return p; //} [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne_Tab16A(ulong v) { if ((long)v <= 0) return (int)((v >> 57) & 0x40) - 1; int j = (int)((0xFFFFFFFFU - v) >> 58) & 0x20; j += (int)((0x0000FFFFU - (v >> j)) >> 59) & 0x10; return j + msb_tab_15[v >> (j + 1)]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne_Tab16B(ulong v) { if ((long)v <= 0) return (int)((v >> 57) & 0x40) - 1; int j; return (j = (j = (int)((0xFFFFFFFFU - v) >> 58) & 0x20) | (int)((0x0000FFFFU - (v >> j)) >> 59) & 0x10) + msb_tab_15[v >> (j + 1)]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne_Tab16C(ulong v) { if ((long)v <= 0) return (int)((v >> 57) & 0x40) - 1; int j; return (j = (j = (int)((0xFFFFFFFFU - v) >> 58) & 0x20) | (int)((0x0000FFFFU - (v >> j)) >> 59) & 0x10) + msb_tab_16[v >> j]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne_Tab16D(ulong v) { if ((long)v <= 0) return (int)((v >> 57) & 0x40) - 1; int j = (int)((0xFFFFFFFFU - v) >> 58) & 0x20; j += (int)((0x0000FFFFU - (v >> j)) >> 59) & 0x10; return j + msb_tab_16[v >> j]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne_Tab8A(ulong v) { if ((long)v <= 0) return (int)((v >> 57) & 64) - 1; int j; j = /**/ (int)((0xFFFFFFFFU - v) >> 58) & 32; j += /**/ (int)((0x0000FFFFU - (v >> j)) >> 59) & 16; j += /**/ (int)((0x000000FFU - (v >> j)) >> 60) & 8; return j + msb_tab_8[v >> j]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne_Tab8B(ulong v) { if ((long)v <= 0) return (int)((v >> 57) & 64) - 1; int j; j = /**/ (int)((0xFFFFFFFFU - v) >> 58) & 32; j += /**/ (int)((0x0000FFFFU - (v >> j)) >> 59) & 16; j += /**/ (int)((0x000000FFU - (v >> j)) >> 60) & 8; return j + msb_tab_7[v >> (j + 1)]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne_NoTab(ulong v) { if ((long)v <= 0) return (int)((v >> 57) & 64) - 1; int j; j = /**/ (int)((0xFFFFFFFFU - v) >> 58) & 32; j += /**/ (int)((0x0000FFFFU - (v >> j)) >> 59) & 16; j += /**/ (int)((0x000000FFU - (v >> j)) >> 60) & 8; j += /**/ (int)((0x0000000FU - (v >> j)) >> 61) & 4; j += /**/ (int)((0x00000003U - (v >> j)) >> 62) & 2; j += /**/ (int)((0x00000001U - (v >> j)) >> 63) & 1; return j; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne_Naive(ulong ul) { if ((long)ul <= 0) return (int)((ul >> 57) & 64) - 1; int o = ul > 0xFFFFFFFFU ? 32 : 0; if ((ul >> o) > 0xFFFFU) o |= 16; if ((ul >> o) > 0xFFU) o |= 8; if ((ul >> o) > 0xFU) o |= 4; if ((ul >> o) > 3U) o |= 2; if ((ul >> o) > 1U) o |= 1; return o; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne_32(ulong ul) { if ((ul & 0xFFFFFFFF00000000) != 0) return alib.Bits._highest_one_bit.HighestOne((uint)(ul >> 32)) + 32; return alib.Bits._highest_one_bit.HighestOne((uint)ul); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// public static class de_Bruijn { [DebuggerBrowsable(DebuggerBrowsableState.Never)] const uint N_bsf32 = 0X077CB531, N_bsr32 = 0X07C4ACDD; [DebuggerBrowsable(DebuggerBrowsableState.Never)] readonly public static sbyte[] bsf32 = { 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9, }, bsr32 = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 }; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOfLSB(uint v) => v != 0 ? bsf32[((v & (uint)-(int)v) * N_bsf32) >> 27] : -1; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint SetTrailing(uint v) { v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; return v; } [DebuggerBrowsable(DebuggerBrowsableState.Never)] readonly public static sbyte[] bsf64 = { 63, 0, 58, 1, 59, 47, 53, 2, 60, 39, 48, 27, 54, 33, 42, 3, 61, 51, 37, 40, 49, 18, 28, 20, 55, 30, 34, 11, 43, 14, 22, 4, 62, 57, 46, 52, 38, 26, 32, 41, 50, 36, 17, 19, 29, 10, 13, 21, 56, 45, 25, 31, 35, 16, 9, 12, 44, 24, 15, 8, 23, 7, 6, 5, }, bsr64 = { 0, 47, 1, 56, 48, 27, 2, 60, 57, 49, 41, 37, 28, 16, 3, 61, 54, 58, 35, 52, 50, 42, 21, 44, 38, 32, 29, 23, 17, 11, 4, 62, 46, 55, 26, 59, 40, 36, 15, 53, 34, 51, 20, 43, 31, 22, 10, 45, 25, 39, 14, 33, 19, 30, 9, 24, 13, 18, 8, 12, 7, 6, 5, 63, }; [DebuggerBrowsable(DebuggerBrowsableState.Never)] const ulong N_bsf64 = 0x07EDD5E59A4E28C2, N_bsr64 = 0x03F79D71B4CB0A89; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexBSF(ulong v) => bsf64[(v * N_bsf64) >> 58]; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexOfLSB(ulong v) => v != 0 ? bsf64[((v & (ulong)-(long)v) * N_bsf64) >> 58] : -1; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int IndexClearLSB(ref ulong v) { if (v == 0) return -1; ulong m = v & (ulong)-(long)v; v ^= m; return bsf64[(m * N_bsf64) >> 58]; } public static int IndexOfMSB(ulong v) { if ((long)v <= 0) return (int)((v >> 57) & 64) - 1; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v |= v >> 32; return bsr64[(v * N_bsr64) >> 58]; } /// rotate qword to the right until the highest bit is set (if possible). /// Useful prior to dividing by a prime for hashing, but be sure to include raw info as well since /// this operation is highly conflating of sparse values public static ulong RorToNeg(this ulong v) { int ix = IndexOfLSB(v) + 1; return (long)v > 0 ? (v >> ix) | (v << (64 - ix)) : v; } /// this one... //PasMPBSRDebruijn64Multiplicator:TPasMPUInt64=TPasMPUInt64($03f79d71b4cb0a89); //PasMPBSRDebruijn64Shift=58; // PasMPBSRDebruijn64Mask=63; // PasMPBSRDebruijn64Table:array[0..63] of TPasMPInt32=(0,47,1,56,48,27,2,60,57,49,41,37,28,16,3,61,54,58,35,52,50,42,21,44,38,32,29,23,17,11,4,62, // 46,55,26,59,40,36,15,53,34,51,20,43,31,22,10,45,25,39,14,33,19,30,9,24,13,18,8,12,7,6,5,63); #if false PasMPCLZDebruijn32Multiplicator=TPasMPUInt32($07c4acdd); PasMPCLZDebruijn32Shift=27; PasMPCLZDebruijn32Mask=31; PasMPCLZDebruijn32Table:array[0..31] of TPasMPInt32=(31,22,30,21,18,10,29,2,20,17,15,13,9,6,28,1,23,19,11,3,16,14,7,24,12,4,8,25,5,26,27,0); PasMPCLZDebruijn64Multiplicator:TPasMPUInt64=TPasMPUInt64($03f79d71b4cb0a89); PasMPCLZDebruijn64Shift=58; PasMPCLZDebruijn64Mask=63; PasMPCLZDebruijn64Table:array[0..63] of TPasMPInt32=(63,16,62,7,15,36,61,3,6,14,22,26,35,47,60,2,9,5,28,11,13,21,42,19,25,31,34,40,46,52,59,1, 17,8,37,4,23,27,48,10,29,12,43,20,32,41,53,18,38,24,49,30,44,33,54,39,50,45,55,51,56,57,58,0); PasMPCTZDebruijn32Multiplicator=TPasMPUInt32($077cb531); PasMPCTZDebruijn32Shift=27; PasMPCTZDebruijn32Mask=31; PasMPCTZDebruijn32Table:array[0..31] of TPasMPInt32=(0,1,28,2,29,14,24,3,30,22,20,15,25,17,4,8,31,27,13,23,21,19,16,7,26,12,18,6,11,5,10,9); PasMPCTZDebruijn64Multiplicator:TPasMPUInt64=TPasMPUInt64($07edd5e59a4e28c2); PasMPCTZDebruijn64Shift=58; PasMPCTZDebruijn64Mask=63; PasMPCTZDebruijn64Table:array[0..63] of TPasMPInt32=(63,0,58,1,59,47,53,2,60,39,48,27,54,33,42,3,61,51,37,40,49,18,28,20,55,30,34,11,43,14,22,4, 62,57,46,52,38,26,32,41,50,36,17,19,29,10,13,21,56,45,25,31,35,16,9,12,44,24,15,8,23,7,6,5); PasMPBSFDebruijn32Multiplicator=TPasMPUInt32($077cb531); PasMPBSFDebruijn32Shift=27; PasMPBSFDebruijn32Mask=31; PasMPBSFDebruijn32Table:array[0..31] of TPasMPInt32=(0,1,28,2,29,14,24,3,30,22,20,15,25,17,4,8,31,27,13,23,21,19,16,7,26,12,18,6,11,5,10,9); PasMPBSFDebruijn64Multiplicator:TPasMPUInt64=TPasMPUInt64($03f79d71b4cb0a89); PasMPBSFDebruijn64Shift=58; PasMPBSFDebruijn64Mask=63; PasMPBSFDebruijn64Table:array[0..63] of TPasMPInt32=(0,1,48,2,57,49,28,3,61,58,50,42,38,29,17,4,62,55,59,36,53,51,43,22,45,39,33,30,24,18,12,5, 63,47,56,27,60,41,37,16,54,35,52,21,44,32,23,11,46,26,40,15,34,20,31,10,25,14,19,9,13,8,7,6); PasMPBSRDebruijn32Multiplicator=TPasMPUInt32($07c4acdd); PasMPBSRDebruijn32Shift=27; PasMPBSRDebruijn32Mask=31; PasMPBSRDebruijn32Table:array[0..31] of TPasMPInt32=(0,9,1,10,13,21,2,29,11,14,16,18,22,25,3,30,8,12,20,28,15,17,24,7,19,27,23,6,26,5,4,31); PasMPBSRDebruijn64Multiplicator:TPasMPUInt64=TPasMPUInt64($03f79d71b4cb0a89); PasMPBSRDebruijn64Shift=58; PasMPBSRDebruijn64Mask=63; PasMPBSRDebruijn64Table:array[0..63] of TPasMPInt32=(0,47,1,56,48,27,2,60,57,49,41,37,28,16,3,61,54,58,35,52,50,42,21,44,38,32,29,23,17,11,4,62, 46,55,26,59,40,36,15,53,34,51,20,43,31,22,10,45,25,39,14,33,19,30,9,24,13,18,8,12,7,6,5,63); #endif #if false const deBruijn64 = 0x0218a392cd3d5dbf var deBruijnIdx64 = [64]byte{ 0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 34, 20, 40, 5, 17, 26, 38, 15, 46, 29, 48, 10, 31, 35, 54, 21, 50, 41, 57, 63, 6, 12, 18, 24, 27, 33, 39, 16, 37, 45, 47, 30, 53, 49, 56, 62, 11, 23, 32, 36, 44, 52, 55, 61, 22, 43, 51, 60, 42, 59, 58, } // Ctz64 counts trailing (low-order) zeroes, // and if all are zero, then 64. func Ctz64(x uint64) int { x &= -x // isolate low-order bit y := x* deBruijn64 >> 58 // extract part of deBruijn sequence i := int (deBruijnIdx64[y]) // convert to bit index z := int ((x - 1) >> 57 & 64) // adjustment if zero return i + z } #endif }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// [SuppressUnmanagedCodeSecurity] public static unsafe class _highest_one_bit_UNMANAGED { [DebuggerBrowsable(DebuggerBrowsableState.Never)] readonly static sbyte* msb_tab_x2; static _highest_one_bit_UNMANAGED() { int i, c; sbyte n; #if WIN32 using (new win32.VmProtector((UIntPtr)0x8000, out sbyte* p)) #else sbyte* p = (sbyte*)GCHandle.Alloc(new sbyte[0x8000], GCHandleType.Pinned).AddrOfPinnedObject(); #endif { msb_tab_x2 = p; for (n = 0, c = 1; n < 16; c <<= 1, n++) for (i = 0; i < c; i += 2) *p++ = n; Debug.Assert(p - msb_tab_x2 == 0x8000); } } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne(sbyte i8) => msb_tab_x2[(byte)i8 >> 1]; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne(byte ui8) => msb_tab_x2[ui8 >> 1]; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne(char ch) => msb_tab_x2[ch >> 1]; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne(short i16) => msb_tab_x2[(ushort)i16 >> 1]; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne(ushort ui16) => msb_tab_x2[ui16 >> 1]; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne(int i32) => HighestOne((uint)i32); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne(uint ui) => ui > 0x0000FFFF ? msb_tab_x2[ui >> 17] + 16 : msb_tab_x2[ui >> 1]; [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne(long i64) => HighestOne_U((ulong)i64); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne_U(ulong v) { if ((long)v <= 0) return (int)((v >> 57) & 64) - 1; int j = v < 0x0000000100000000UL ? (v < 0x0000000000010000UL ? 0 : 16) : (v < 0x0001000000000000UL ? 32 : 48); return msb_tab_x2[v >> (j + 1)] + j; } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// [SuppressUnmanagedCodeSecurity] public static class _old_1 { [DebuggerBrowsable(DebuggerBrowsableState.Never)] readonly static sbyte[] highest_one_16; static _old_1() { int i, c, j; sbyte n; var p = new sbyte[0x10000]; p[0] = -1; j = 1; for (n = 0, c = 1; n < 16; c <<= 1, n++) for (i = 0; i < c; i++) p[j++] = n; highest_one_16 = p; } //public static int HighestOne(sbyte i8) => highest_one_16[i8]; //public static int HighestOne(byte ui8) => highest_one_16[ui8]; //public static int HighestOne(char ch) => highest_one_16[ch]; //public static int HighestOne(short i16) => highest_one_16[i16]; //public static int HighestOne(ushort ui16) => highest_one_16[ui16]; //public static int HighestOne(int i32) => HighestOne((uint)i32); //public static int HighestOne(uint ui32) //{ // int i; // return (i = highest_one_16[ui32 >> 16]) < 0 ? // highest_one_16[(ushort)ui32] : (i + 16); //} //public static int HighestOne( long i64) => HighestOne((ulong)i64); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne_Old1(ulong ui64) { int i, j; return (i = highest_one_16[ui64 >> (j = 48)]) < 0 && (i = highest_one_16[ui64 >> (j = 32)]) < 0 && (i = highest_one_16[ui64 >> (j = 16)]) < 0 ? highest_one_16[(ushort)ui64] : (i + j); } }; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// [SuppressUnmanagedCodeSecurity] public static class _old_2 { [DebuggerBrowsable(DebuggerBrowsableState.Never)] readonly static sbyte[] msb_tab_x2; static _old_2() { int i, c, j; sbyte n; var p = new sbyte[0x8000]; j = 0; for (n = 0, c = 1; n < 16; c <<= 1, n++) for (i = 0; i < c; i += 2) p[j++] = n; msb_tab_x2 = p; } //public static int HighestOne(sbyte i8) => msb_tab_x2[(byte)i8 >> 1]; //public static int HighestOne(byte ui8) => msb_tab_x2[ui8 >> 1]; //public static int HighestOne(char ch) => msb_tab_x2[ch >> 1]; //public static int HighestOne(short i16) => msb_tab_x2[(ushort)i16 >> 1]; //public static int HighestOne(ushort ui16) => msb_tab_x2[ui16 >> 1]; //public static int HighestOne(int i32) => HighestOne((uint)i32); //public static int HighestOne(uint ui) => ui > 0x0000FFFF ? msb_tab_x2[ui >> 17] + 16 : msb_tab_x2[ui >> 1]; //public static int HighestOne( long i64) => HighestOne((ulong)i64); [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int HighestOne_Old2(ulong ul) { return ul > 0x0000FFFFFFFFFFFF ? msb_tab_x2[ul >> 49] + 48 : ul > 0x00000000FFFFFFFF ? msb_tab_x2[ul >> 33] + 32 : ul > 0x000000000000FFFF ? msb_tab_x2[ul >> 17] + 16 : ul != 0 ? msb_tab_x2[ul >> 1] : -1; } }; }