swift - 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 在编码浮点数时不添加数字吗?
解决方案
首先,请务必阅读浮点数学是否损坏?和浮点指南。如果您需要一个特定小数位数的值,那么您不需要 Float。Float 表示数字的二进制表示,对于有限的位数,它可能不等于十进制表示。
Swift 有一个数字的十进制表示,称为 Decimal:
let value = Decimal(string: "3.402823e-20")!
JSONEncoder 不会将 Decimal 编码为科学记数法,因此它将被编码为0.00000000000000000003402823
,但它将是精确的十进制值。要修改格式,您需要重新实现 JSONEncoder。它不支持任意数字格式。
或者,如果您想要一个特定的字符串,则需要在 JSON 中将其编码为字符串而不是数字,并使用 NumberFormatter 来获取所需的有效位数。
请注意,这也可能会在解析方面对您不利。JSON 以十进制数字定义数字,但我所知道的解析器实际上没有以这种方式解码它们。我知道的每个解析器都将它们解码为某种二进制浮点数,它可能不完全等于 JSON 中的值。
如果您需要发送方和接收方通过 JSON 就非整数数字的确切值达成一致,您有两个不错的选择:通过按某个值缩放使用定点编码,然后编码为整数(例如,存储美分作为整数而不是小数美元),或者将数字编码为字符串并自己处理解析。
推荐阅读
- android - Flutter - Activity Tracker App - 步数、楼上/楼下、静止
- javascript - 角度基于权限的路由
- reactjs - 如何在 React 中获取 API 响应?
- json - 找不到名称“JSON”打字稿文件
- bash - 如何删除字符串中的 \r\n 并将字符串转换为数组
- node.js - 没有互联网访问时,纱线运行节点非常慢
- c - WIN32 - 除静态文本(标签)外的隐藏控件工作
- c# - 使用
给出空指针 - python - NameError:未定义名称“BertModel”,导入 Bert 提取摘要器时出错
- javascript - 如何将普通节点服务器转换为可执行文件?