| File: Utilities\BitUtils.cs | Web Access |
| Project: src\src\Microsoft.ML.Core\Microsoft.ML.Core.csproj (Microsoft.ML.Core) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System.Runtime.CompilerServices; using Microsoft.ML.Runtime; namespace Microsoft.ML.Internal.Utilities { internal static partial class Utils { private const int CbitUint = 32; private const int CbitUlong = 64; // Various bit/byte manipulation methods. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong MakeUlong(uint uHi, uint uLo) { return ((ulong)uHi << CbitUint) | uLo; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint GetLo(ulong uu) { return (uint)uu; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint GetHi(ulong uu) { return (uint)(uu >> CbitUint); } public static uint Abs(int a) { uint mask = (uint)(a >> 31); return ((uint)a ^ mask) - mask; } public static ulong Abs(long a) { ulong mask = (ulong)(a >> 63); return ((ulong)a ^ mask) - mask; } public static int CbitHighZero(uint u) { if (u == 0) return 32; int cbit = 0; if ((u & 0xFFFF0000) == 0) { cbit += 16; u <<= 16; } if ((u & 0xFF000000) == 0) { cbit += 8; u <<= 8; } if ((u & 0xF0000000) == 0) { cbit += 4; u <<= 4; } if ((u & 0xC0000000) == 0) { cbit += 2; u <<= 2; } if ((u & 0x80000000) == 0) cbit += 1; return cbit; } public static int IbitHigh(uint u) { if (u == 0) return -1; int ibit = 31; if ((u & 0xFFFF0000) == 0) { ibit -= 16; u <<= 16; } if ((u & 0xFF000000) == 0) { ibit -= 8; u <<= 8; } if ((u & 0xF0000000) == 0) { ibit -= 4; u <<= 4; } if ((u & 0xC0000000) == 0) { ibit -= 2; u <<= 2; } if ((u & 0x80000000) == 0) ibit -= 1; return ibit; } public static int CbitLowZero(uint u) { if (u == 0) return 32; int cbit = 0; if ((u & 0x0000FFFF) == 0) { cbit += 16; u >>= 16; } if ((u & 0x000000FF) == 0) { cbit += 8; u >>= 8; } if ((u & 0x0000000F) == 0) { cbit += 4; u >>= 4; } if ((u & 0x00000003) == 0) { cbit += 2; u >>= 2; } if ((u & 0x00000001) == 0) cbit += 1; return cbit; } public static int CbitHighZero(ulong uu) { if ((uu & 0xFFFFFFFF00000000) == 0) return 32 + CbitHighZero(GetLo(uu)); return CbitHighZero(GetHi(uu)); } public static int CbitLowZero(ulong uu) { uint u = GetLo(uu); if (u == 0) return 32 + CbitLowZero(GetHi(uu)); return CbitLowZero(u); } public static int Cbit(uint u) { u = (u & 0x55555555) + ((u >> 1) & 0x55555555); u = (u & 0x33333333) + ((u >> 2) & 0x33333333); u = (u & 0x0F0F0F0F) + ((u >> 4) & 0x0F0F0F0F); u = (u & 0x00FF00FF) + ((u >> 8) & 0x00FF00FF); return (int)((ushort)u + (ushort)(u >> 16)); } public static int Cbit(ulong uu) { uu = (uu & 0x5555555555555555) + ((uu >> 1) & 0x5555555555555555); uu = (uu & 0x3333333333333333) + ((uu >> 2) & 0x3333333333333333); uu = (uu & 0x0F0F0F0F0F0F0F0F) + ((uu >> 4) & 0x0F0F0F0F0F0F0F0F); uu = (uu & 0x00FF00FF00FF00FF) + ((uu >> 8) & 0x00FF00FF00FF00FF); uu = (uu & 0x0000FFFF0000FFFF) + ((uu >> 16) & 0x0000FFFF0000FFFF); return (int)(GetLo(uu) + GetHi(uu)); } // Builds a mask with bits below ibit all set. Only works for 0 <= ibit < 32. // Use MaskBelowEx to extend to 0 <= ibit < 64, in particular, for 32. public static uint UMaskBelow(int ibit) { Contracts.Assert(0 <= ibit && ibit < CbitUint, "UMaskBelow is designed to work for 0 <= ibit < 32"); return (uint)(1U << ibit) - 1; } // Builds a mask with bits below ibit all set. Only works for 0 <= ibit < 64. public static uint UMaskBelowEx(int ibit) { Contracts.Assert(0 <= ibit && ibit < CbitUlong, "UMaskBelowEx is designed to work for 0 <= ibit < 64"); // To handle 32 <= ibit < 64 properly, we have to start with 1LU, since otherwise the C# compiler only shifts // by the low 5 bits of ibit. return (uint)(1LU << ibit) - 1; } // Builds a mask with bits below ibit all set. Only works for 0 <= ibit < 64. public static ulong UuMaskBelow(int ibit) { Contracts.Assert(0 <= ibit && ibit < CbitUlong, "UuMaskBelow is designed to work for 0 <= ibit < 64"); return (1LU << ibit) - 1; } public static bool IsPowerOfTwo(int x) { return (x & (x - 1)) == 0; } public static bool IsPowerOfTwo(uint x) { return (x & (x - 1)) == 0; } public static bool IsPowerOfTwo(long x) { return (x & (x - 1)) == 0; } public static bool IsPowerOfTwo(ulong x) { return (x & (x - 1)) == 0; } } }