diff --git a/Src/Newtonsoft.Json.Tests/Issues/Issue2768.cs b/Src/Newtonsoft.Json.Tests/Issues/Issue2768.cs index bb3c8f658..6681c2a73 100644 --- a/Src/Newtonsoft.Json.Tests/Issues/Issue2768.cs +++ b/Src/Newtonsoft.Json.Tests/Issues/Issue2768.cs @@ -74,6 +74,22 @@ public void Test_Deserialize() Assert.AreEqual("0.0", d.ToString()); } + [Test] + public void Test_Deserialize_Negative() + { + decimal d = JsonConvert.DeserializeObject("-0.0"); + + Assert.AreEqual("0.0", d.ToString()); + } + + [Test] + public void Test_Deserialize_NegativeNoTrailingZero() + { + decimal d = JsonConvert.DeserializeObject("-0"); + + Assert.AreEqual("0", d.ToString()); + } + [Test] public void Test_Deserialize_MultipleTrailingZeroes() { @@ -100,18 +116,18 @@ public void ParseJsonDecimal() FloatParseHandling = FloatParseHandling.Decimal }; - decimal? parsedDecimal = null; + decimal? parsedValue = null; while (reader.Read()) { if (reader.TokenType == JsonToken.Float) { - parsedDecimal = (decimal)reader.Value; + parsedValue = (decimal)reader.Value; break; } } - Assert.AreEqual("0.0", parsedDecimal.ToString()); + Assert.AreEqual("0.0", parsedValue.ToString()); } [Test] @@ -144,7 +160,42 @@ public void ParseJsonDecimal_IsBoxedInstanceSame() #else Assert.IsFalse(object.ReferenceEquals(boxedDecimals[0], boxedDecimals[1])); #endif + } + [Test] + public void Test_Deserialize_Double_Negative() + { + double d = JsonConvert.DeserializeObject("-0.0"); + +#if NETCOREAPP3_1_OR_GREATER + Assert.AreEqual("-0", d.ToString()); +#else + Assert.AreEqual("0", d.ToString()); +#endif + } + + [Test] + public void Test_Deserialize_Double_NegativeNoTrailingZero() + { + double d = JsonConvert.DeserializeObject("-0"); + +#if NETCOREAPP3_1_OR_GREATER + Assert.AreEqual("-0", d.ToString()); +#else + Assert.AreEqual("0", d.ToString()); +#endif + } + + [Test] + public void JValueDouble_ToString() + { + var d = new JValue(-0.0d); + +#if NETCOREAPP3_1_OR_GREATER + Assert.AreEqual("-0", d.ToString()); +#else + Assert.AreEqual("0", d.ToString()); +#endif } } } diff --git a/Src/Newtonsoft.Json/Utilities/BoxedPrimitives.cs b/Src/Newtonsoft.Json/Utilities/BoxedPrimitives.cs index 2b19cd0a9..c2019e6b5 100644 --- a/Src/Newtonsoft.Json/Utilities/BoxedPrimitives.cs +++ b/Src/Newtonsoft.Json/Utilities/BoxedPrimitives.cs @@ -131,7 +131,8 @@ internal static object Get(double value) { if (value == 0.0d) { - return DoubleZero; + // Double supports -0.0. Detection logic from https://stackoverflow.com/a/4739883/11829. + return double.IsNegativeInfinity(1.0 / value) ? DoubleNegativeZero : DoubleZero; } if (double.IsInfinity(value)) { @@ -147,6 +148,7 @@ internal static object Get(double value) internal static readonly object DoubleNaN = double.NaN; internal static readonly object DoublePositiveInfinity = double.PositiveInfinity; internal static readonly object DoubleNegativeInfinity = double.NegativeInfinity; - internal static readonly object DoubleZero = (double)0; + internal static readonly object DoubleZero = 0.0d; + internal static readonly object DoubleNegativeZero = -0.0d; } }