【发布时间】:2018-01-22 22:23:58
【问题描述】:
基本上问题是在这个例子中:
let d1 = NSNumber(value: 1.4);
let d2 = d1.doubleValue;
let f1 = NSNumber(value: Float(1.4));
let f2 = d1.floatValue;
d1 结果 1.4
d2 结果 1.3999999999999999
f1 结果 1.4
f2 结果 1.3999999999999998
有人知道这是为什么吗?
我正在尝试解析 JSON 文件,例如:
{"name": "something", "version": 1.4}
使用以下代码:
let json = try (JSONSerialization.jsonObject(with: someData) as? [String: Any])!;
let version: Double = (json["version"] as! NSNumber).doubleValue;
或
let version: Double = json["version"] as! Double;
或
let version: Double = json["version"] as! Float;
而我就是无法获得 1.4...
四舍五入对我来说不是解决方案,因为我想将此数字写回 JSON 文件,该文件将被 由其他程序/语言解析,并且需要正好是 1.4在文件中。
有什么建议吗?
更新:问题只存在于 1.1 和 1.4。 没有问题 1.2, 1.3, 1.5
更新 2:序列化代码:
let jsonDict: Dictionary<String,Any> = [
"name" : name,
"version" : version
];
let data = try? JSONSerialization.data(withJSONObject: jsonDict, options: []);
let jsonString = String(data:data, encoding:.utf8);
【问题讨论】:
-
您是否尝试使用浮点对象来保存版本号?不要那样做。版本号不是数学数字。它们是标识字符串。将其作为字符串保存并操作。
-
考虑将字符串转换为
NSDecimalNumber -
@DimitarAtanasov:不可能将“1.4”解析为二进制浮点中的 1.4,因为 1.4 不能用二进制浮点表示。如果您坚持使用数字格式进行版本标识,则必须使用十进制浮点格式。 (顺便说一句,你指向的 JSON 信息说“数字是一个十进制数字序列,没有多余的前导零。”它只定义了这个字符序列,而不是解释为数学数字或其他方式。它说“JSON不知道数字的语义。”)您可以查看 NSDecimal。
-
@DimitarAtanasov:1.5 可以精确表示。在 1.3 中,发生的舍入错误恰好可以解决。
-
了解根本问题是成功的一半。我无法为解决方案做出贡献,因为我不熟悉 Swift。但我会重申@EricPostpischil 所说的 - JSON 文件中包含的所有内容都是一个字符串,如果您的程序正在读取或写入一个数字,那么某个地方正在转换它。您需要更严格地控制该转换。显然 Decimal 类型进行了不同的转换。
标签: macos floating-point double swift4