首页 > 解决方案 > JSONEncoder encode Float 在小数点后添加更多数字

问题描述

我有一个Float(4.502823e-20),我将它传递给 JSONEncoder 进行编码,例如,

JSONEncoder().encode(float)

当我检查从上述调用返回的数据的内容时,我看到了这些值

52 46 53 48 50 56 50 50 57 54 57 48 54 48 53 52 48 54 101 45 50 48

这转化为ASCII:

4.5028229690605406e-20

它的数字比我的输入多3.402823e-20

4.50282 29690605406 e-20

你能告诉我如何让 JSONEncoder 在编码浮点数时不添加数字吗?

标签: swift

解决方案


首先,请务必阅读浮点数学是否损坏?浮点指南。如果您需要一个特定小数位数的值,那么您不需要 Float。Float 表示数字的二进制表示,对于有限的位数,它可能不等于十进制表示。

Swift 有一个数字的十进制表示,称为 Decimal:

let value = Decimal(string: "3.402823e-20")!

JSONEncoder 不会将 Decimal 编码为科学记数法,因此它将被编码为0.00000000000000000003402823,但它将是精确的十进制值。要修改格式,您需要重新实现 JSONEncoder。它不支持任意数字格式。

或者,如果您想要一个特定的字符串,则需要在 JSON 中将其编码为字符串而不是数字,并使用 NumberFormatter 来获取所需的有效位数。

请注意,这也可能会在解析方面对您不利。JSON 以十进制数字定义数字,但我所知道的解析器实际上没有以这种方式解码它们。我知道的每个解析器都将它们解码为某种二进制浮点数,它可能不完全等于 JSON 中的值。

如果您需要发送方和接收方通过 JSON 就非整数数字的确切值达成一致,您有两个不错的选择:通过按某个值缩放使用定点编码,然后编码为整数(例如,存储美分作为整数而不是小数美元),或者将数字编码为字符串并自己处理解析。


推荐阅读