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:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2021-02-28 03:50:33 +0300
committerGitHub <noreply@github.com>2021-02-28 03:50:33 +0300
commitae5d71611b274f9bab047932037adfc16c1199c1 (patch)
tree77edb6bfae7b40e8fe97ffb4ff3e148dc92927d6
parentec21beea1763aa539e1084e595a86a58d444036e (diff)
[release/6.0-preview2] Track trailing zeros only for floating point numbers (#48857)
* Track trailing zeros only for floating point numbers * Undo previous unit test change * Add a roundtrip unit test * Move check outside the loop * Globalization * Also fix #48648 and unit tests * Assert and unit test Co-authored-by: Prashanth Govindarajan <prgovi@microsoft.com>
-rw-r--r--src/libraries/System.Formats.Cbor/tests/Writer/CborWriterTests.Tag.cs2
-rw-r--r--src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs34
-rw-r--r--src/libraries/System.Runtime/tests/System/DecimalTests.cs8
-rw-r--r--src/libraries/System.Runtime/tests/System/DoubleTests.cs7
-rw-r--r--src/libraries/System.Runtime/tests/System/HalfTests.cs5
-rw-r--r--src/libraries/System.Runtime/tests/System/Int32Tests.cs6
-rw-r--r--src/libraries/System.Runtime/tests/System/SingleTests.cs6
7 files changed, 53 insertions, 15 deletions
diff --git a/src/libraries/System.Formats.Cbor/tests/Writer/CborWriterTests.Tag.cs b/src/libraries/System.Formats.Cbor/tests/Writer/CborWriterTests.Tag.cs
index 88cb2f0ee95..b9cc53ceb23 100644
--- a/src/libraries/System.Formats.Cbor/tests/Writer/CborWriterTests.Tag.cs
+++ b/src/libraries/System.Formats.Cbor/tests/Writer/CborWriterTests.Tag.cs
@@ -158,7 +158,7 @@ namespace System.Formats.Cbor.Tests
[InlineData("1", "c4820001")]
[InlineData("-1", "c4820020")]
[InlineData("1.1", "c482200b")]
- [InlineData("1.000", "c4820001")]
+ [InlineData("1.000", "c482221903e8")]
[InlineData("273.15", "c48221196ab3")]
[InlineData("79228162514264337593543950335", "c48200c24cffffffffffffffffffffffff")] // decimal.MaxValue
[InlineData("7922816251426433759354395033.5", "c48220c24cffffffffffffffffffffffff")]
diff --git a/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs b/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs
index a07153cad25..382eb1ccf82 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Number.Parsing.cs
@@ -358,9 +358,10 @@ namespace System
{
number.Scale++;
}
- else if (digCount < maxDigCount)
+
+ if (digCount < maxDigCount)
{
- // Handle a case like "53.0". We need to ignore trailing zeros in the fractional part, so we keep a count of the number of trailing zeros and update digCount later
+ // Handle a case like "53.0". We need to ignore trailing zeros in the fractional part for floating point numbers, so we keep a count of the number of trailing zeros and update digCount later
if (ch == '0')
{
numberOfTrailingZeros++;
@@ -395,17 +396,8 @@ namespace System
}
bool negExp = false;
- if (digEnd == maxDigCount && numberOfTrailingZeros > 0 && number.HasNonZeroTail)
- {
- // We have a non-zero digit in the input past maxDigitCount. We already handle this properly.
- number.DigitsCount = digEnd;
- }
- else
- {
- // We have trailing 0s in the fractional part. We can strip it all out
- number.DigitsCount = digEnd - numberOfTrailingZeros;
- }
- number.Digits[number.DigitsCount] = (byte)('\0');
+ number.DigitsCount = digEnd;
+ number.Digits[digEnd] = (byte)('\0');
if ((state & StateDigits) != 0)
{
if ((ch == 'E' || ch == 'e') && ((styles & NumberStyles.AllowExponent) != 0))
@@ -449,6 +441,20 @@ namespace System
ch = p < strEnd ? *p : '\0';
}
}
+
+ if (number.Kind == NumberBufferKind.FloatingPoint && !number.HasNonZeroTail)
+ {
+ // Adjust the number buffer for trailing zeros
+ int numberOfFractionalDigits = digEnd - number.Scale;
+ if (numberOfFractionalDigits > 0)
+ {
+ numberOfTrailingZeros = Math.Min(numberOfTrailingZeros, numberOfFractionalDigits);
+ Debug.Assert(numberOfTrailingZeros >= 0);
+ number.DigitsCount = digEnd - numberOfTrailingZeros;
+ number.Digits[number.DigitsCount] = (byte)('\0');
+ }
+ }
+
while (true)
{
if (!IsWhite(ch) || (styles & NumberStyles.AllowTrailingWhite) == 0)
@@ -2025,7 +2031,7 @@ namespace System
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe char* MatchNegativeSignChars(char* p, char* pEnd, NumberFormatInfo info)
{
- char *ret = MatchChars(p, pEnd, info.NegativeSign);
+ char* ret = MatchChars(p, pEnd, info.NegativeSign);
if (ret == null && info.AllowHyphenDuringParsing && p < pEnd && *p == '-')
{
ret = p + 1;
diff --git a/src/libraries/System.Runtime/tests/System/DecimalTests.cs b/src/libraries/System.Runtime/tests/System/DecimalTests.cs
index e4f3c9d8012..35069a81e61 100644
--- a/src/libraries/System.Runtime/tests/System/DecimalTests.cs
+++ b/src/libraries/System.Runtime/tests/System/DecimalTests.cs
@@ -1500,6 +1500,14 @@ namespace System.Tests
Assert.Throws<FormatException>(() => f.ToString("E" + intMaxPlus1String));
}
+ [Theory]
+ [InlineData("3.00")]
+ public void TestRoundTripDecimalToString(string input)
+ {
+ decimal d = Decimal.Parse(input, NumberStyles.Number, NumberFormatInfo.InvariantInfo);
+ string dString = d.ToString(CultureInfo.InvariantCulture);
+ Assert.Equal(input, dString);
+ }
public static IEnumerable<object[]> Truncate_TestData()
{
yield return new object[] { 123m, 123m };
diff --git a/src/libraries/System.Runtime/tests/System/DoubleTests.cs b/src/libraries/System.Runtime/tests/System/DoubleTests.cs
index 8403fe131d6..d0bfcfb4141 100644
--- a/src/libraries/System.Runtime/tests/System/DoubleTests.cs
+++ b/src/libraries/System.Runtime/tests/System/DoubleTests.cs
@@ -290,6 +290,13 @@ namespace System.Tests
yield return new object[] { "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", defaultStyle, invariantFormat, 0.0 };
yield return new object[] { "0.005", defaultStyle, invariantFormat, 0.005 };
yield return new object[] { "0.0500", defaultStyle, invariantFormat, 0.05 };
+ yield return new object[] { "6250000000000000000000000000000000e-12", defaultStyle, invariantFormat, 6.25e21 };
+ yield return new object[] { "6250000e0", defaultStyle, invariantFormat, 6.25e6 };
+ yield return new object[] { "6250100e-5", defaultStyle, invariantFormat, 62.501 };
+ yield return new object[] { "625010.00e-4", defaultStyle, invariantFormat, 62.501 };
+ yield return new object[] { "62500e-4", defaultStyle, invariantFormat, 6.25 };
+ yield return new object[] { "62500", defaultStyle, invariantFormat, 62500.0 };
+ yield return new object[] { "10e-3", defaultStyle, invariantFormat, 0.01 };
yield return new object[] { (123.1).ToString(), NumberStyles.AllowDecimalPoint, null, 123.1 };
yield return new object[] { (1000.0).ToString("N0"), NumberStyles.AllowThousands, null, 1000.0 };
diff --git a/src/libraries/System.Runtime/tests/System/HalfTests.cs b/src/libraries/System.Runtime/tests/System/HalfTests.cs
index e851f28815f..926034b5b70 100644
--- a/src/libraries/System.Runtime/tests/System/HalfTests.cs
+++ b/src/libraries/System.Runtime/tests/System/HalfTests.cs
@@ -685,6 +685,11 @@ namespace System.Tests
yield return new object[] { "0.000000000000000000", defaultStyle, invariantFormat, 0.0f };
yield return new object[] { "0.005", defaultStyle, invariantFormat, 0.005f };
yield return new object[] { "0.0400", defaultStyle, invariantFormat, 0.04f };
+ yield return new object[] { "1200e0", defaultStyle, invariantFormat, 1200.0f };
+ yield return new object[] { "120100e-4", defaultStyle, invariantFormat, 12.01f };
+ yield return new object[] { "12010.00e-4", defaultStyle, invariantFormat, 1.201f };
+ yield return new object[] { "12000e-4", defaultStyle, invariantFormat, 1.2f };
+ yield return new object[] { "1200", defaultStyle, invariantFormat, 1200.0f };
yield return new object[] { (123.1f).ToString(), NumberStyles.AllowDecimalPoint, null, 123.1f };
yield return new object[] { (1000.0f).ToString("N0"), NumberStyles.AllowThousands, null, 1000.0f };
diff --git a/src/libraries/System.Runtime/tests/System/Int32Tests.cs b/src/libraries/System.Runtime/tests/System/Int32Tests.cs
index f64df4bcc31..fca800ca292 100644
--- a/src/libraries/System.Runtime/tests/System/Int32Tests.cs
+++ b/src/libraries/System.Runtime/tests/System/Int32Tests.cs
@@ -355,6 +355,12 @@ namespace System.Tests
yield return new object[] { "123123", NumberStyles.AllowLeadingSign, new NumberFormatInfo() { NegativeSign = "123" }, -123 };
yield return new object[] { "123123", NumberStyles.AllowLeadingSign, new NumberFormatInfo() { PositiveSign = "12312" }, 3 };
yield return new object[] { "123123", NumberStyles.AllowLeadingSign, new NumberFormatInfo() { NegativeSign = "12312" }, -3 };
+
+ // Test trailing zeros
+ yield return new object[] { "3.00", NumberStyles.Number, CultureInfo.InvariantCulture, 3 };
+ yield return new object[] { "3.00000000", NumberStyles.Number, CultureInfo.InvariantCulture, 3 };
+ yield return new object[] { "3.000000000", NumberStyles.Number, CultureInfo.InvariantCulture, 3 };
+ yield return new object[] { "3.0000000000", NumberStyles.Number, CultureInfo.InvariantCulture, 3 };
}
[Theory]
diff --git a/src/libraries/System.Runtime/tests/System/SingleTests.cs b/src/libraries/System.Runtime/tests/System/SingleTests.cs
index 1fa4916c172..962621d05c1 100644
--- a/src/libraries/System.Runtime/tests/System/SingleTests.cs
+++ b/src/libraries/System.Runtime/tests/System/SingleTests.cs
@@ -295,6 +295,12 @@ namespace System.Tests
yield return new object[] { "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", defaultStyle, invariantFormat, 0.0f };
yield return new object[] { "0.005", defaultStyle, invariantFormat, 0.005f };
yield return new object[] { "0.0500", defaultStyle, invariantFormat, 0.05f };
+ yield return new object[] { "6250000000000000000000000000000000e-12", defaultStyle, invariantFormat, 6.25e21f };
+ yield return new object[] { "6250000e0", defaultStyle, invariantFormat, 6.25e6f };
+ yield return new object[] { "6250100e-5", defaultStyle, invariantFormat, 62.501f };
+ yield return new object[] { "625010.00e-4", defaultStyle, invariantFormat, 62.501f };
+ yield return new object[] { "62500e-4", defaultStyle, invariantFormat, 6.25f };
+ yield return new object[] { "62500", defaultStyle, invariantFormat, 62500.0f };
yield return new object[] { (123.1f).ToString(), NumberStyles.AllowDecimalPoint, null, 123.1f };
yield return new object[] { (1000.0f).ToString("N0"), NumberStyles.AllowThousands, null, 1000.0f };