Ale*_*ane 1 ios swift siesta-swift
我正在尝试向服务器执行HTTP请求:内容是一个JSON对象,其中包含键“金额”的数字值。如果“金额”是带有十进制数字的值,例如1.6,则请求将包含值1.6000000000000001,并且服务器不接受该值(api是Java编写的,类型是float。我无法发送服务器的字符串,因为从我那里接收数据的API只能接受“金额”的数字。我尝试使用Siesta Framework或dataTask执行请求,但结果始终相同
这就是我创建请求的方式(我省略了不太重要的部分)
let jsonData = try! JSONSerialization.data(withJSONObject: jsonObject) // jsonObject contains the Double value "amount"
let request = URLRequest(url: url)
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request)
task.resume()
Run Code Online (Sandbox Code Playgroud)
没有可以完全重现该问题的代码,很难确定,但是我想您会看到这种行为:
let amount = 1.6 // Double
let jsonObject = ["amount": amount]
let jsonData = try! JSONSerialization.data(withJSONObject: jsonObject)
String(data: jsonData, encoding: String.Encoding.utf8)
Run Code Online (Sandbox Code Playgroud)
Swift Foundation的JSON序列化始终将数字值格式化为它们的全精度-因此,双精度数字1.6的格式为1.6000000000000001。
如果服务器接受,则可以并且应该发送一个字符串:
let amount = "1.6" // String
let jsonObject = ["amount": amount]
let jsonData = try! JSONSerialization.data(withJSONObject: jsonObject)
String(data: jsonData, encoding: String.Encoding.utf8)
Run Code Online (Sandbox Code Playgroud)
请注意,如果您处理的是金钱或其他需要精确值的事物,则字符串是发送此值的唯一正确方法:即使1.6将其拼写为,标准JSON解析器也可能会将其转换为接收端的浮点数。 。
如果您出于某种原因只需要以较低的精度格式化它以使其在服务器上通过验证,则可以将其作为Decimal而不是a 嵌入到JSON中,Double并且将采用不同的格式:
let amount = 1.6
let jsonObject = ["amount": Decimal(amount)]
let jsonData = try! JSONSerialization.data(withJSONObject: jsonObject)
String(data: jsonData, encoding: String.Encoding.utf8)
// {"amount":1.6}
Run Code Online (Sandbox Code Playgroud)
您甚至可以操纵将Decimal其舍入到一定精度。
但是请注意,这并不能使您免受浮点精度问题的困扰:您仍在根据JSON规范发送浮点数,并且它很可能仍会在接收端解析为浮点数。
| 归档时间: |
|
| 查看次数: |
461 次 |
| 最近记录: |