Bug 15885 – float serialized to JSON loses precision

Status
RESOLVED
Resolution
FIXED
Severity
major
Priority
P1
Component
phobos
Product
D
Version
D2
Platform
All
OS
All
Creation time
2016-04-06T12:29:56Z
Last change time
2020-03-21T03:56:39Z
Assigned to
Basile-z
Creator
Rory

Attachments

IDFilenameSummaryContent-TypeSize
1594patchpossible patchtext/plain460

Comments

Comment #0 by rjmcguire — 2016-04-06T12:29:56Z
I've marked this issue as major because a lot of people are using JSON for mobile app communication, and I discovered this because an incorrect invoice was sent (fortunately only during testing). In this code: import std.json; import std.stdio; void main() { JSONValue json; json.type = JSON_TYPE.FLOAT; json.floating = 30738.22; writeln(toJSON(&json)); } the resulting output is: 30738.2 The problem is that all float serialization just uses to!string() from std.conv; std.json should serialize to the standard @ json.org.
Comment #1 by rjmcguire — 2016-04-06T13:42:13Z
Created attachment 1594 possible patch this patch just makes sure we always output using %f. I'm guessing %g technically has the bug because surely it shouldn't just remove part of the number _by default_
Comment #2 by b2.temp — 2016-05-21T20:40:56Z
(In reply to Rory from comment #1) > Created attachment 1594 [details] > possible patch > > this patch just makes sure we always output using %f. I'm guessing %g > technically has the bug because surely it shouldn't just remove part of the > number _by default_ %f doesn't work. It breaks some unittest. the correct format specifier would be "%.9g" (9 comes from the constant FLT_DECIMAL_DIG). see https://github.com/dlang/phobos/pull/4343
Comment #3 by thomas.bockman — 2016-05-22T02:37:51Z
The correct format specifier is ACTUALLY "%.18g", assuming that you want full lossless conversion. This is because: 1) JSON_TYPE.FLOAT is a 64-bit double, not 32-bit float! 2) cast(int)ceil(log(pow(2.0L, F.mant_dig - 1)) / log(10.0L) + 1) decimal digits are needed to represent some floating-point values, such as (1 + F.epsilon). See this DPaste: https://dpaste.dzfl.pl/1bd14e5c3f83#line-25
Comment #4 by github-bugzilla — 2016-06-01T05:31:16Z
Commits pushed to master at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/7a486d9d038448595c74aa4ef4bd7d9e952a4b64 Fix issue 15885 - numeric values serialized to JSON lose precision. https://github.com/dlang/phobos/commit/f4ad734aad6e3b2dd4881508d2b15eebb732a26c Merge pull request #4345 from tsbockman/issue-15885-tsb Fix issue 15885 - float serialized to JSON loses precision
Comment #5 by github-bugzilla — 2016-10-01T11:44:57Z
Commits pushed to stable at https://github.com/dlang/phobos https://github.com/dlang/phobos/commit/7a486d9d038448595c74aa4ef4bd7d9e952a4b64 Fix issue 15885 - numeric values serialized to JSON lose precision. https://github.com/dlang/phobos/commit/f4ad734aad6e3b2dd4881508d2b15eebb732a26c Merge pull request #4345 from tsbockman/issue-15885-tsb