Fixes preserving trailing zeros when deserializing decimals (#1368)

* Fixes preserving trailing zeros when deserializing decimals

* Update to use constant.
This commit is contained in:
Tyler Brinkley
2017-07-09 11:58:12 +12:00
committed by James Newton-King
parent fa7cccbd2f
commit 8cfddc4da5
2 changed files with 13 additions and 29 deletions
@@ -184,6 +184,8 @@ namespace Newtonsoft.Json.Tests.Utilities
Assert.AreEqual(expectedValue.Value, d, "Input string: " + s); Assert.AreEqual(expectedValue.Value, d, "Input string: " + s);
Assert.AreEqual(expectedValue.Value, d2, "DecimalTryParse result is not equal to decimal.Parse. Input string: " + s); Assert.AreEqual(expectedValue.Value, d2, "DecimalTryParse result is not equal to decimal.Parse. Input string: " + s);
Assert.AreEqual(expectedValue.Value.ToString(), d.ToString());
} }
} }
@@ -196,6 +198,10 @@ namespace Newtonsoft.Json.Tests.Utilities
AssertDecimalTryParse("-1", ParseResult.Success, -1M); AssertDecimalTryParse("-1", ParseResult.Success, -1M);
AssertDecimalTryParse("1E1", ParseResult.Success, 10M); AssertDecimalTryParse("1E1", ParseResult.Success, 10M);
AssertDecimalTryParse("1E28", ParseResult.Success, 10000000000000000000000000000M); AssertDecimalTryParse("1E28", ParseResult.Success, 10000000000000000000000000000M);
AssertDecimalTryParse("1.0", ParseResult.Success, 1.0M);
AssertDecimalTryParse("1.10000", ParseResult.Success, 1.10000M);
AssertDecimalTryParse("1000.000000000000", ParseResult.Success, 1000.000000000000M);
AssertDecimalTryParse("87.50", ParseResult.Success, 87.50M);
AssertDecimalTryParse("1.2345678901234567890123456789", ParseResult.Success, 1.2345678901234567890123456789M); AssertDecimalTryParse("1.2345678901234567890123456789", ParseResult.Success, 1.2345678901234567890123456789M);
AssertDecimalTryParse("1.0000000000000000000000000001", ParseResult.Success, 1.0000000000000000000000000001M); AssertDecimalTryParse("1.0000000000000000000000000001", ParseResult.Success, 1.0000000000000000000000000001M);
+7 -29
View File
@@ -1536,7 +1536,7 @@ namespace Newtonsoft.Json.Utilities
} }
else else
{ {
value = (hi19 * DecimalFactors[mantissaDigits - 20]) + lo10; value = (hi19 / new decimal(1, 0, 0, false, (byte)(mantissaDigits - 19))) + lo10;
} }
if (exponent > 0) if (exponent > 0)
@@ -1550,7 +1550,7 @@ namespace Newtonsoft.Json.Utilities
{ {
if (exponent > 1) if (exponent > 1)
{ {
value *= DecimalFactors[exponent - 2]; value /= new decimal(1, 0, 0, false, (byte)(exponent - 1));
if (value > decimalMaxValueHi28) if (value > decimalMaxValueHi28)
{ {
return ParseResult.Overflow; return ParseResult.Overflow;
@@ -1560,7 +1560,7 @@ namespace Newtonsoft.Json.Utilities
} }
else else
{ {
value *= DecimalFactors[exponent - 1]; value /= new decimal(1, 0, 0, false, (byte)exponent);
} }
} }
else else
@@ -1573,18 +1573,17 @@ namespace Newtonsoft.Json.Utilities
{ {
if (mantissaDigits + exponent + 28 <= 0) if (mantissaDigits + exponent + 28 <= 0)
{ {
value = 0M; value = isNegative ? -0M : 0M;
return ParseResult.Success; return ParseResult.Success;
} }
if (exponent >= -28) if (exponent >= -28)
{ {
value /= DecimalFactors[-exponent - 1]; value *= new decimal(1, 0, 0, false, (byte)(-exponent));
} }
else else
{ {
decimal[] decimalFactors = DecimalFactors; value /= 1e28M;
value /= decimalFactors[27]; value *= new decimal(1, 0, 0, false, (byte)(-exponent - 28));
value /= decimalFactors[-exponent - 29];
} }
} }
} }
@@ -1597,27 +1596,6 @@ namespace Newtonsoft.Json.Utilities
return ParseResult.Success; return ParseResult.Success;
} }
private static decimal[] _decimalFactors;
private static decimal[] DecimalFactors
{
get
{
decimal[] decimalFactors = _decimalFactors;
if (decimalFactors == null)
{
decimalFactors = new decimal[28];
decimal last = 1M;
for (int i = 0; i < decimalFactors.Length; ++i)
{
decimalFactors[i] = last *= 10M;
}
_decimalFactors = decimalFactors;
}
return decimalFactors;
}
}
public static bool TryConvertGuid(string s, out Guid g) public static bool TryConvertGuid(string s, out Guid g)
{ {
// GUID has to have format 00000000-0000-0000-0000-000000000000 // GUID has to have format 00000000-0000-0000-0000-000000000000