Skip to content

Commit c908de3

Browse files
authored
Fix not returning negative double from box cache (#2777)
1 parent 2afdccd commit c908de3

File tree

2 files changed

+58
-5
lines changed

2 files changed

+58
-5
lines changed

Src/Newtonsoft.Json.Tests/Issues/Issue2768.cs

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,22 @@ public void Test_Deserialize()
7474
Assert.AreEqual("0.0", d.ToString());
7575
}
7676

77+
[Test]
78+
public void Test_Deserialize_Negative()
79+
{
80+
decimal d = JsonConvert.DeserializeObject<decimal>("-0.0");
81+
82+
Assert.AreEqual("0.0", d.ToString());
83+
}
84+
85+
[Test]
86+
public void Test_Deserialize_NegativeNoTrailingZero()
87+
{
88+
decimal d = JsonConvert.DeserializeObject<decimal>("-0");
89+
90+
Assert.AreEqual("0", d.ToString());
91+
}
92+
7793
[Test]
7894
public void Test_Deserialize_MultipleTrailingZeroes()
7995
{
@@ -100,18 +116,18 @@ public void ParseJsonDecimal()
100116
FloatParseHandling = FloatParseHandling.Decimal
101117
};
102118

103-
decimal? parsedDecimal = null;
119+
decimal? parsedValue = null;
104120

105121
while (reader.Read())
106122
{
107123
if (reader.TokenType == JsonToken.Float)
108124
{
109-
parsedDecimal = (decimal)reader.Value;
125+
parsedValue = (decimal)reader.Value;
110126
break;
111127
}
112128
}
113129

114-
Assert.AreEqual("0.0", parsedDecimal.ToString());
130+
Assert.AreEqual("0.0", parsedValue.ToString());
115131
}
116132

117133
[Test]
@@ -144,7 +160,42 @@ public void ParseJsonDecimal_IsBoxedInstanceSame()
144160
#else
145161
Assert.IsFalse(object.ReferenceEquals(boxedDecimals[0], boxedDecimals[1]));
146162
#endif
163+
}
147164

165+
[Test]
166+
public void Test_Deserialize_Double_Negative()
167+
{
168+
double d = JsonConvert.DeserializeObject<double>("-0.0");
169+
170+
#if NETCOREAPP3_1_OR_GREATER
171+
Assert.AreEqual("-0", d.ToString());
172+
#else
173+
Assert.AreEqual("0", d.ToString());
174+
#endif
175+
}
176+
177+
[Test]
178+
public void Test_Deserialize_Double_NegativeNoTrailingZero()
179+
{
180+
double d = JsonConvert.DeserializeObject<double>("-0");
181+
182+
#if NETCOREAPP3_1_OR_GREATER
183+
Assert.AreEqual("-0", d.ToString());
184+
#else
185+
Assert.AreEqual("0", d.ToString());
186+
#endif
187+
}
188+
189+
[Test]
190+
public void JValueDouble_ToString()
191+
{
192+
var d = new JValue(-0.0d);
193+
194+
#if NETCOREAPP3_1_OR_GREATER
195+
Assert.AreEqual("-0", d.ToString());
196+
#else
197+
Assert.AreEqual("0", d.ToString());
198+
#endif
148199
}
149200
}
150201
}

Src/Newtonsoft.Json/Utilities/BoxedPrimitives.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,8 @@ internal static object Get(double value)
131131
{
132132
if (value == 0.0d)
133133
{
134-
return DoubleZero;
134+
// Double supports -0.0. Detection logic from https://stackoverflow.com/a/4739883/11829.
135+
return double.IsNegativeInfinity(1.0 / value) ? DoubleNegativeZero : DoubleZero;
135136
}
136137
if (double.IsInfinity(value))
137138
{
@@ -147,6 +148,7 @@ internal static object Get(double value)
147148
internal static readonly object DoubleNaN = double.NaN;
148149
internal static readonly object DoublePositiveInfinity = double.PositiveInfinity;
149150
internal static readonly object DoubleNegativeInfinity = double.NegativeInfinity;
150-
internal static readonly object DoubleZero = (double)0;
151+
internal static readonly object DoubleZero = 0.0d;
152+
internal static readonly object DoubleNegativeZero = -0.0d;
151153
}
152154
}

0 commit comments

Comments
 (0)