// 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.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.Intrinsics.X86; namespace System.Buffers.Text { internal static partial class FormattingHelpers { [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountDigits(ulong value) { int digits = 1; uint part; if (value >= 10000000) { if (value >= 100000000000000) { part = (uint)(value / 100000000000000); digits += 14; } else { part = (uint)(value / 10000000); digits += 7; } } else { part = (uint)value; } if (part < 10) { // no-op } else if (part < 100) { digits += 1; } else if (part < 1000) { digits += 2; } else if (part < 10000) { digits += 3; } else if (part < 100000) { digits += 4; } else if (part < 1000000) { digits += 5; } else { Debug.Assert(part < 10000000); digits += 6; } return digits; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountDigits(uint value) { int digits = 1; if (value >= 100000) { value = value / 100000; digits += 5; } if (value < 10) { // no-op } else if (value < 100) { digits += 1; } else if (value < 1000) { digits += 2; } else if (value < 10000) { digits += 3; } else { Debug.Assert(value < 100000); digits += 4; } return digits; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountHexDigits(ulong value) { if (Lzcnt.X64.IsSupported) { int right = 64 - (int)Lzcnt.X64.LeadingZeroCount(value | 1); return (right + 3) >> 2; } int digits = 1; if (value > 0xFFFFFFFF) { digits += 8; value >>= 0x20; } if (value > 0xFFFF) { digits += 4; value >>= 0x10; } if (value > 0xFF) { digits += 2; value >>= 0x8; } if (value > 0xF) digits++; return digits; } // Counts the number of trailing '0' digits in a decimal number. // e.g., value = 0 => retVal = 0, valueWithoutTrailingZeros = 0 // value = 1234 => retVal = 0, valueWithoutTrailingZeros = 1234 // value = 320900 => retVal = 2, valueWithoutTrailingZeros = 3209 [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int CountDecimalTrailingZeros(uint value, out uint valueWithoutTrailingZeros) { int zeroCount = 0; if (value != 0) { while (true) { uint temp = value / 10; if (value != (temp * 10)) { break; } value = temp; zeroCount++; } } valueWithoutTrailingZeros = value; return zeroCount; } } }