From 1acd737dc869218f3e8d2a89bf7fb297fd71e232 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 4 Apr 2018 22:19:47 -0400 Subject: [PATCH] Move FormattingHelpers.Count{Hex}Digits from Utf8Formatter into shared --- .../System.Private.CoreLib.Shared.projitems | 1 + .../Text/FormattingHelpers.CountDigits.cs | 132 ++++++++++++++++++ 2 files changed, 133 insertions(+) create mode 100644 src/mscorlib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs diff --git a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems index d5c432e128af..542c91e2f60e 100644 --- a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems +++ b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems @@ -52,6 +52,7 @@ + diff --git a/src/mscorlib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs b/src/mscorlib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs new file mode 100644 index 000000000000..709ac4fba615 --- /dev/null +++ b/src/mscorlib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs @@ -0,0 +1,132 @@ +// 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; + +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) + { + // TODO: When x86 intrinsic support comes online, experiment with implementing this using lzcnt. + // return 16 - (int)((uint)Lzcnt.LeadingZeroCount(value | 1) >> 3); + + 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; + } + } +}