Open florianreinhart opened 6 years ago
I dug into this a little more. Here is what I’ve found.
There is an issue tracking the double/string conversion issue: SR-106: description returns a rounded value of Double.
I also looked into the open source implementation of JSONEncoder and JSONSerialization. They use a CFNumberFormatter to format floating point values and wrap them in an NSNumber first: https://github.com/apple/swift-corelibs-foundation/blob/6501fa20bf4c5f36627ce3dce73ffc190ba41c0b/Foundation/JSONSerialization.swift#L438
However, this produces different results as on Apple platforms. I filed SR-7195: JSONSerialization encodes Double differently on Darwin and Linux.
A short term fix that we could implement: String(format: "%.16e", self)
The age-old floating point issues bit me once again...
Note: This most definitely also applies to
Float
, but I have just tested withDouble
.When Swift formats a
Double
as aString
it rounds the number, e.g. an internal representation of7.7087009966199993
has a String value of7.70870099662
. When you create aDouble
from thatString
, you get back7.7087009966200002
. This is closer to7.70870099662
than7.7087009966199993
, so it is the right thing to do here.mysql-swift uses the
String
initializer to convert numbers to strings and hands it off to MySQL client. I believe the server then decodes that string in much the same way Swift does: The string7.70870099662
is converted to the double value7.7087009966200002
.JSONEncoder
/JSONDecoder
does not observe these issues and formats the double value as7.7087009966199993
. We should probably look into theCodable
implementation ofDouble
and figure out how they encode floating point values.I have created a sample implementation to reproduce the issue: