Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 0c00ba8

Browse files
committed
Chante to prefer float/double over decimal
1 parent e0e44a3 commit 0c00ba8

2 files changed

Lines changed: 75 additions & 27 deletions

File tree

src/ServiceStack.Text/Common/DeserializeType.cs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -155,32 +155,41 @@ public static object ParsePrimitive(string value)
155155

156156
bool boolValue;
157157
if (bool.TryParse(value, out boolValue)) return boolValue;
158+
float floatValue;
159+
double doubleValue;
158160

159161
decimal decimalValue;
160162
if (decimal.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out decimalValue))
161163
{
162-
if (!JsConfig.TryToParseNumericType)
163-
return decimalValue;
164+
if (!JsConfig.TryToParseNumericType)
165+
return decimalValue;
164166

165167
if (decimalValue == decimal.Truncate(decimalValue))
166-
{
167-
if (decimalValue <= byte.MaxValue && decimalValue >= byte.MinValue) return (byte)decimalValue;
168-
if (decimalValue <= sbyte.MaxValue && decimalValue >= sbyte.MinValue) return (sbyte)decimalValue;
169-
if (decimalValue <= Int16.MaxValue && decimalValue >= Int16.MinValue) return (Int16)decimalValue;
170-
if (decimalValue <= UInt16.MaxValue && decimalValue >= UInt16.MinValue) return (UInt16)decimalValue;
171-
if (decimalValue <= Int32.MaxValue && decimalValue >= Int32.MinValue) return (Int32)decimalValue;
172-
if (decimalValue <= UInt32.MaxValue && decimalValue >= UInt32.MinValue) return (UInt32)decimalValue;
173-
if (decimalValue <= Int64.MaxValue && decimalValue >= Int64.MinValue) return (Int64)decimalValue;
174-
if (decimalValue <= UInt64.MaxValue && decimalValue >= UInt64.MinValue) return (UInt64)decimalValue;
168+
{
169+
if (decimalValue <= byte.MaxValue && decimalValue >= byte.MinValue) return (byte)decimalValue;
170+
if (decimalValue <= sbyte.MaxValue && decimalValue >= sbyte.MinValue) return (sbyte)decimalValue;
171+
if (decimalValue <= Int16.MaxValue && decimalValue >= Int16.MinValue) return (Int16)decimalValue;
172+
if (decimalValue <= UInt16.MaxValue && decimalValue >= UInt16.MinValue) return (UInt16)decimalValue;
173+
if (decimalValue <= Int32.MaxValue && decimalValue >= Int32.MinValue) return (Int32)decimalValue;
174+
if (decimalValue <= UInt32.MaxValue && decimalValue >= UInt32.MinValue) return (UInt32)decimalValue;
175+
if (decimalValue <= Int64.MaxValue && decimalValue >= Int64.MinValue) return (Int64)decimalValue;
176+
if (decimalValue <= UInt64.MaxValue && decimalValue >= UInt64.MinValue) return (UInt64)decimalValue;
175177
}
178+
179+
if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out floatValue))
180+
return floatValue;
181+
182+
if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue))
183+
return doubleValue;
184+
176185
return decimalValue;
177186
}
178187

179-
float floatValue;
180-
if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out floatValue)) return floatValue;
188+
if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out floatValue))
189+
return floatValue;
181190

182-
double doubleValue;
183-
if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue)) return doubleValue;
191+
if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out doubleValue))
192+
return doubleValue;
184193

185194
return null;
186195
}

tests/ServiceStack.Text.Tests/DictionaryTests.cs

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Collections.Specialized;
44
using System.Diagnostics;
5+
using System.Globalization;
56
using NUnit.Framework;
67
using ServiceStack.Text.Tests.DynamicModels.DataModel;
78

@@ -279,19 +280,57 @@ public NumericType(decimal min,decimal max,Type type)
279280
public Type Type { get; private set; }
280281
}
281282

282-
[Test]
283-
public void deserizes_signed_bytes_into_to_best_fit_numeric()
284-
{
285-
JsConfig.TryToParsePrimitiveTypeValues = true;
286-
JsConfig.TryToParseNumericType = true;
283+
[Test]
284+
public void deserizes_signed_bytes_into_to_best_fit_numeric()
285+
{
286+
JsConfig.TryToParsePrimitiveTypeValues = true;
287+
JsConfig.TryToParseNumericType = true;
288+
289+
var deserializedDict = JsonSerializer.DeserializeFromString<IDictionary<string, object>>("{\"min\":-128,\"max\":127}");
290+
Assert.That(deserializedDict["min"], Is.TypeOf<sbyte>());
291+
Assert.That(deserializedDict["min"], Is.EqualTo(sbyte.MinValue));
292+
//it seemed strange having zero return as a signed byte
293+
Assert.That(deserializedDict["max"], Is.TypeOf<byte>());
294+
Assert.That(deserializedDict["max"], Is.EqualTo(sbyte.MaxValue));
295+
}
287296

288-
var deserializedDict = JsonSerializer.DeserializeFromString<IDictionary<string, object>>("{\"min\":-128,\"max\":127}");
289-
Assert.That(deserializedDict["min"], Is.TypeOf<sbyte>());
290-
Assert.That(deserializedDict["min"], Is.EqualTo(sbyte.MinValue));
291-
//it seemed strange having zero return as a signed byte
292-
Assert.That(deserializedDict["max"], Is.TypeOf<byte>());
293-
Assert.That(deserializedDict["max"], Is.EqualTo(sbyte.MaxValue));
294-
}
297+
[Test]
298+
public void deserizes_floats_into_to_best_fit_floating_point()
299+
{
300+
JsConfig.TryToParsePrimitiveTypeValues = true;
301+
JsConfig.TryToParseNumericType = true;
302+
var decimalFmt = "n50";
303+
304+
float floatValue = 1.1f;
305+
//TODO find a number that doesn't suck which throws in float.Parse() but not double.Parse()
306+
double doubleValue = double.MaxValue - Math.Pow(2, 1000);
307+
var intValue = int.MaxValue;
308+
var longValue = long.MaxValue;
309+
310+
float notFloat;
311+
Assert.That(!float.TryParse(doubleValue.ToString(), out notFloat));
312+
313+
var toFloatValue = float.Parse(floatValue.ToString());
314+
Assert.AreEqual(toFloatValue, floatValue, 1);
315+
var toDoubleValue = double.Parse(doubleValue.ToString());
316+
Assert.AreEqual(toDoubleValue, doubleValue, Math.Pow(2, 1000));
317+
318+
var json = "{{\"float\":{0},\"double\":{1},\"int\":{2},\"long\":{3}}}"
319+
.Fmt(floatValue, doubleValue, intValue, longValue);
320+
var map = JsonSerializer.DeserializeFromString<IDictionary<string, object>>(json);
321+
322+
Assert.That(map["float"], Is.TypeOf<float>());
323+
Assert.That(map["float"], Is.EqualTo(floatValue));
324+
325+
Assert.That(map["double"], Is.TypeOf<double>());
326+
Assert.AreEqual((double)map["double"], doubleValue, Math.Pow(2, 1000));
327+
328+
Assert.That(map["int"], Is.TypeOf<int>());
329+
Assert.That(map["int"], Is.EqualTo(intValue));
330+
331+
Assert.That(map["long"], Is.TypeOf<long>());
332+
Assert.That(map["long"], Is.EqualTo(longValue));
333+
}
295334

296335
[Test]
297336
public void deserizes_signed_types_into_to_best_fit_numeric()

0 commit comments

Comments
 (0)