为什么要在JSON中使用字符串来表示十进制数

问题描述 投票:25回答:2

某些API(如paypal API)在JSON中使用字符串类型来表示十进制数。所以"7.47"而不是7.47

为什么/何时使用json数值类型是个好主意? AFAIK数值类型允许无限精度以及科学记数法。

json serialization paypal
2个回答
38
投票

将JSON中的数值作为字符串传输的主要原因是为了消除传输中的任何精度损失或模糊性。

确实,JSON规范没有为数值指定精度。这并不意味着JSON数字具有无限精度。这意味着未指定数字精度,这意味着JSON实现可以自由选择任何方便其实现或目标的数字精度。如果您的应用程序具有特定的精度要求,那么这种可变性可能会很痛苦。

精度损失通常在数值的JSON编码中不明显(1.7很好且简洁),但在接收端的JSON解析和中间表示中表现出来。 JSON解析函数可以合理地将1.7解析为IEEE双精度浮点数。但是,有限长度/有限精度表示总是会遇到无法精确表示的数字。无理数(如pi和e)永远不能在有限系统中准确表示。 1.7具有十进制(基数10)表示法的有限表示,但在二进制(基数2)中,它是无理数 - 无限数字系列。

因此,将1.7解析为内存中的浮点数,然后打印出数字可能会返回类似1.69而不是1.7的内容。

JSON 1.7值的消费者可以使用更复杂的技术来解析和保留内存中的值,例如使用定点数据类型或具有任意精度的“string int”数据类型,但这并不能完全消除某些数字的转换精度损失。实际情况是,很少有JSON解析器为这种极端措施而烦恼,因为大多数情况下的好处都很低,内存和CPU成本很高。

因此,如果您想要向消费者发送精确的数值并且您不希望将值自动转换为典型的内部数字表示,那么您最好的选择是将数值作为字符串发送出去并准确告诉消费者如果需要对数字操作执行数字操作,应该如何处理该字符串。

例如:在一些JSON生成器(JRuby,一个)中,BigInteger值自动输出为JSON作为字符串,主要是因为BigInteger的范围和精度比IEEE双精度浮点数大得多。将BigInteger值减小为两倍以便作为JSON数字输出通常会丢失有效数字。

此外,JSON规范(http://www.json.org/)明确指出NaN和无穷大(INF)对JSON数值无效。如果需要表达这些边缘元素,则不能使用JSON编号。您必须使用字符串或对象结构。

最后,还有另一个方面可以导致选择将数字数据作为字符串发送:控制显示格式。前导零和尾随零对数值无关紧要。如果您发送JSON数值2.10或004,转换为内部数字形式后,它们将显示为2.1和4。

如果您要发送的数据将直接显示给用户,您可能希望您的资金数字在屏幕上很好地排列,十进制对齐。一种方法是让客户端负责格式化数据以便显示。另一种方法是让服务器格式化数据以供显示。客户端可能更容易在屏幕上显示内容,但是如果客户端还需要对值进行计算,这会使得从字符串中提取数值变得困难。


3
投票

Summarized Version

刚引用@dthorpe的回答,我认为这是最重要的一点:

此外,JSON规范(http://www.json.org/)明确指出NaN和无穷大(INF)对JSON数值无效。如果需要表达这些边缘元素,则不能使用JSON编号。您必须使用字符串或对象结构。

© www.soinside.com 2019 - 2024. All rights reserved.