Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/System.Private.CoreLib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs')
-rw-r--r--src/System.Private.CoreLib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs b/src/System.Private.CoreLib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs
new file mode 100644
index 000000000..b6140adba
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/System/Buffers/Text/FormattingHelpers.CountDigits.cs
@@ -0,0 +1,161 @@
+// 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;
+ }
+
+
+ // 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;
+ }
+ }
+}