diff --git a/src/FSharp.Data.Json.Core/JsonValue.fs b/src/FSharp.Data.Json.Core/JsonValue.fs index bc8b7406a..e028641c5 100644 --- a/src/FSharp.Data.Json.Core/JsonValue.fs +++ b/src/FSharp.Data.Json.Core/JsonValue.fs @@ -86,7 +86,13 @@ type JsonValue = | Boolean b -> w.Write(if b then "true" else "false") | Number number -> w.Write number | Float v when Double.IsInfinity v || Double.IsNaN v -> w.Write "null" - | Float number -> w.Write number + | Float number -> + let s = number.ToString("R", CultureInfo.InvariantCulture) + w.Write s + // Ensure the output looks like a float (has a decimal point or exponent), + // so that round-tripping through JSON preserves the Float type. + if s.IndexOfAny([| '.'; 'E'; 'e' |]) = -1 then + w.Write ".0" | String s -> w.Write "\"" JsonValue.JsonStringEncodeTo w s diff --git a/tests/FSharp.Data.Core.Tests/JsonValue.fs b/tests/FSharp.Data.Core.Tests/JsonValue.fs index 6505ad4ae..846061255 100644 --- a/tests/FSharp.Data.Core.Tests/JsonValue.fs +++ b/tests/FSharp.Data.Core.Tests/JsonValue.fs @@ -293,6 +293,20 @@ let ``Serializes special float value as null`` v = let json = JsonValue.Float v json.ToString(JsonSaveOptions.DisableFormatting) |> should equal "null" +[] +let ``Float value 100.0 serializes with decimal point`` () = + // Regression test for https://github.com/fsprojects/FSharp.Data/issues/1356 + // JsonValue.Float(100.0) should serialize as "100.0", not "100" + JsonValue.Float(100.0).ToString(JsonSaveOptions.DisableFormatting) |> should equal "100.0" + +[] +let ``Float value with fractional part serializes correctly`` () = + JsonValue.Float(100.5).ToString(JsonSaveOptions.DisableFormatting) |> should equal "100.5" + +[] +let ``Float value in scientific notation serializes correctly`` () = + JsonValue.Float(1e20).ToString(JsonSaveOptions.DisableFormatting) |> should equal "1E+20" + let normalize (str:string) = str.Replace("\r\n", "\n") .Replace("\r", "\n")