相关疑难解决方法(0)

通过Swift 4中的JSONDecoder传递数字时失去精度

我正在向我们的服务器发送一些JSON数据,并且在使用新的Swift 4 JSONDecoder编码某些值时出现问题.以这个游乐场为例:

import Foundation

struct QuantyTest: Codable {
    var name: String
    var value: Float
}

let json = """
[
    {
        "name": "Length",
        "value": 9.87
    },
    {
        "name": "Width",
        "value": 9.95
    }
]
""".data(using: .utf8)!

let decoder = JSONDecoder()
var size = try decoder.decode([QuantyTest].self, from: json)
let encoder = JSONEncoder()
var encodSize = try? encoder.encode(size)
print(String(data: encodSize!, encoding: .utf8)!)
Run Code Online (Sandbox Code Playgroud)

所以我首先解码JSON并打印出结果(大小).输出看起来像这样:

[{name "Length", value 9.87}, {name "Width", value 9.95}]
Run Code Online (Sandbox Code Playgroud)

一切都很好,但是当我使用Swift JSONEncoder将(大小)编码回JSON时,我得到以下输出:

[{"name":"Length","value":9.869999885559082},{"name":"Width","value":9.9499998092651367}]
Run Code Online (Sandbox Code Playgroud)

我已经尝试将值更改为十进制或双倍但我有类似的问题,十进制输出如下所示:

[{"name":"Length","value":9.869999999999997952},{"name":"Width","value":9.95}]
Run Code Online (Sandbox Code Playgroud)

并作为双重:

[{"name":"Length","value":9.8699999999999992},{"name":"Width","value":9.9499999999999993}]
Run Code Online (Sandbox Code Playgroud)

我知道浮点数,双精度数或十进制数不是超精确的,但我不明白为什么输出窗口在使用float时显示正确的值,直到我通过JSONEncoder.我不确定如何绕过这一个,任何建议将不胜感激.

json ios swift4

8
推荐指数
0
解决办法
1292
查看次数

从 JSON 中解析 Decimal 作为字符串

使用 Xcode 10.2 和 iOS 12.x,我们能够从 json 字符串中提取 Decimal。使用 Xcode 11.1 和 iOS 13.1 会引发异常

预期解码 Double,但发现了字符串/数据。

class MyClass : Codable {

     var decimal: Decimal?
 }
Run Code Online (Sandbox Code Playgroud)

然后尝试解析它

let json = "{\"decimal\":\"0.007\"}"
let data = json.data(using: .utf8)
let decoder = JSONDecoder()
decoder.nonConformingFloatDecodingStrategy = .convertFromString(positiveInfinity: "s1", negativeInfinity: "s2", nan: "s3")
 do {
   let t = try decoder.decode(MyClass.self, from: data!)
 } catch {
   print(error)
 }
Run Code Online (Sandbox Code Playgroud)

如果我将 json 字符串更改为

let json = "{\"decimal\":0.007}"

它有效,但我们又失去了精度。有任何想法吗?

swift codable ios13

3
推荐指数
1
解决办法
2668
查看次数

如何在不损失精度的情况下解码 NSDecimalNumber?

有没有办法告诉 JSONDecoder 将传入的小数转换为字符串?

 public struct Transaction: Decodable
 {
    public let total: NSDecimalNumber?


    enum CodingKeys: String, CodingKey {
        case total = "AMOUNT"

    }

    public init(from decoder: Decoder) throws
    {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        let total = try values.decode(Decimal.self, forKey: .total)
        self.total = NSDecimalNumber(decimal: total);
    }

 }
Run Code Online (Sandbox Code Playgroud)

考虑当 AMOUNT 类似于 397289527598234759823475455622342424358363514.42 时会发生什么

我想使用我拥有的代码,我会得到 nonConformingFloatDecodingStrategy 异常而无法从中恢复或失去精度。

围绕愚蠢的 swift Decimal 的斗争被记录在了所有的地方,特别是在这里:

使 NSDecimalNumber 可编码

nsdecimalnumber swift codable jsondecoder

1
推荐指数
1
解决办法
266
查看次数

标签 统计

codable ×2

swift ×2

ios ×1

ios13 ×1

json ×1

jsondecoder ×1

nsdecimalnumber ×1

swift4 ×1