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

github.com/dotnet/runtime.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanner Gooding <tagoo@outlook.com>2022-08-24 16:48:54 +0300
committergithub-actions <github-actions@github.com>2022-08-25 02:10:22 +0300
commit995dbf788671385050a5bdb7a648fbd8f346a38e (patch)
tree6d9baa3e5eaeb921b5d1e2f513dc90064d10de73
parent7fac450bbbaf05d694c4ee878815f864a47c4952 (diff)
Fix FormattingHelpers.CountDigits(UInt128) and add more tests for Int128/UInt128.ToStringbackport/pr-74501-to-release/7.0
-rw-r--r--src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs23
-rw-r--r--src/libraries/System.Runtime/tests/System/Int128Tests.cs6
-rw-r--r--src/libraries/System.Runtime/tests/System/UInt128Tests.cs8
3 files changed, 33 insertions, 4 deletions
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs
index fd6ce30c9e1..22eff2b8b16 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Buffers/Text/FormattingHelpers.CountDigits.cs
@@ -14,22 +14,37 @@ namespace System.Buffers.Text
{
ulong upper = value.Upper;
- if (upper < 5)
+ // 1e19 is 8AC7_2304_89E8_0000
+ // 1e20 is 5_6BC7_5E2D_6310_0000
+ // 1e21 is 36_35C9_ADC5_DEA0_0000
+
+ if (upper == 0)
{
+ // We have less than 64-bits, so just return the lower count
return CountDigits(value.Lower);
}
- int digits = 19;
+ // We have more than 1e19, so we have at least 20 digits
+ int digits = 20;
if (upper > 5)
{
- digits++;
+ // ((2^128) - 1) / 1e20 < 34_02_823_669_209_384_635 which
+ // is 18.5318 digits, meaning the result definitely fits
+ // into 64-bits and we only need to add the lower digit count
+
value /= new UInt128(0x5, 0x6BC7_5E2D_6310_0000); // value /= 1e20
+ Debug.Assert(value.Upper == 0);
+
digits += CountDigits(value.Lower);
}
- else if (value.Lower >= 0x6BC75E2D63100000)
+ else if ((upper == 5) && (value.Lower >= 0x6BC75E2D63100000))
{
+ // We're greater than 1e20, but definitely less than 1e21
+ // so we have exactly 21 digits
+
digits++;
+ Debug.Assert(digits == 21);
}
return digits;
diff --git a/src/libraries/System.Runtime/tests/System/Int128Tests.cs b/src/libraries/System.Runtime/tests/System/Int128Tests.cs
index 15f1a39a023..036872f0ddc 100644
--- a/src/libraries/System.Runtime/tests/System/Int128Tests.cs
+++ b/src/libraries/System.Runtime/tests/System/Int128Tests.cs
@@ -116,6 +116,12 @@ namespace System.Tests
yield return new object[] { (Int128)(-4567), defaultSpecifier, defaultFormat, "-4567" };
yield return new object[] { (Int128)0, defaultSpecifier, defaultFormat, "0" };
yield return new object[] { (Int128)4567, defaultSpecifier, defaultFormat, "4567" };
+ yield return new object[] { new Int128(0x0000_0000_0000_0001, 0x0000_0000_0000_0003), defaultSpecifier, defaultFormat, "18446744073709551619" };
+ yield return new object[] { new Int128(0x0000_0000_0000_0001, 0x0000_0000_0000_000A), defaultSpecifier, defaultFormat, "18446744073709551626" };
+ yield return new object[] { new Int128(0x0000_0000_0000_0005, 0x0000_0000_0000_0001), defaultSpecifier, defaultFormat, "92233720368547758081" };
+ yield return new object[] { new Int128(0x0000_0000_0000_0005, 0x6BC7_5E2D_6310_0000), defaultSpecifier, defaultFormat, "100000000000000000000" };
+ yield return new object[] { new Int128(0x0000_0000_0000_0036, 0x35C9_ADC5_DEA0_0000), defaultSpecifier, defaultFormat, "1000000000000000000000" };
+ yield return new object[] { new Int128(0x0013_4261_72C7_4D82, 0x2B87_8FE8_0000_0000), defaultSpecifier, defaultFormat, "100000000000000000000000000000000000" };
yield return new object[] { Int128.MaxValue, defaultSpecifier, defaultFormat, "170141183460469231731687303715884105727" };
}
diff --git a/src/libraries/System.Runtime/tests/System/UInt128Tests.cs b/src/libraries/System.Runtime/tests/System/UInt128Tests.cs
index a02f205e72f..a255a044496 100644
--- a/src/libraries/System.Runtime/tests/System/UInt128Tests.cs
+++ b/src/libraries/System.Runtime/tests/System/UInt128Tests.cs
@@ -101,6 +101,14 @@ namespace System.Tests
{
yield return new object[] { (UInt128)0, defaultSpecifier, defaultFormat, "0" };
yield return new object[] { (UInt128)4567, defaultSpecifier, defaultFormat, "4567" };
+ yield return new object[] { new UInt128(0x0000_0000_0000_0001, 0x0000_0000_0000_0003), defaultSpecifier, defaultFormat, "18446744073709551619" };
+ yield return new object[] { new UInt128(0x0000_0000_0000_0001, 0x0000_0000_0000_000A), defaultSpecifier, defaultFormat, "18446744073709551626" };
+ yield return new object[] { new UInt128(0x0000_0000_0000_0005, 0x0000_0000_0000_0001), defaultSpecifier, defaultFormat, "92233720368547758081" };
+ yield return new object[] { new UInt128(0x0000_0000_0000_0005, 0x6BC7_5E2D_6310_0000), defaultSpecifier, defaultFormat, "100000000000000000000" };
+ yield return new object[] { new UInt128(0x0000_0000_0000_0036, 0x35C9_ADC5_DEA0_0000), defaultSpecifier, defaultFormat, "1000000000000000000000" };
+ yield return new object[] { new UInt128(0x0013_4261_72C7_4D82, 0x2B87_8FE8_0000_0000), defaultSpecifier, defaultFormat, "100000000000000000000000000000000000" };
+ yield return new object[] { new UInt128(0x7FFF_FFFF_FFFF_FFFF, 0xFFFF_FFFF_FFFF_FFFF), defaultSpecifier, defaultFormat, "170141183460469231731687303715884105727" };
+ yield return new object[] { new UInt128(0x8000_0000_0000_0000, 0x0000_0000_0000_0000), defaultSpecifier, defaultFormat, "170141183460469231731687303715884105728" };
yield return new object[] { UInt128.MaxValue, defaultSpecifier, defaultFormat, "340282366920938463463374607431768211455" };
}