为什么要在JSON中使用字符串表示十进制数字 [英] Why would you use a string in JSON to represent a decimal number

查看:112
本文介绍了为什么要在JSON中使用字符串表示十进制数字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

某些API,例如 paypal API 使用JSON中的字符串类型,代表十进制数字.因此,用"7.47"代替7.47.

Some APIs, like the paypal API use a string type in JSON to represent a decimal number. So "7.47" instead of 7.47.

为什么/何时使用json数字值类型是个好主意? AFAIK数字值类型允许无限精度和科学计数法.

Why/when would this be a good idea over using the json number value type? AFAIK the number value type allows for infinite precision as well as scientific notation.

推荐答案

将JSON中的数字值作为字符串传输的主要原因是为了消除传输中的精度或歧义性.

The main reason to transfer numeric values in JSON as strings is to eliminate any loss of precision or ambiguity in transfer.

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

It's true that the JSON spec does not specify a precision for numeric values. This does not mean that JSON numbers have infinite precision. It means that numeric precision is not specified, which means JSON implementations are free to choose whatever numeric precision is convenient to their implementation or goals. It is this variability that can be a pain if your application has specific precision requirements.

精度损失通常在数值的JSON编码中不明显(1.7很好且简洁),但在接收端的JSON解析和中间表示中体现出来. JSON解析功能可以相当合理地将1.7解析为IEEE双精度浮点数.但是,有限长度/有限精度的十进制表示形式总是会遇到其十进制扩展不能表示为有限的数字序列的数字:

Loss of precision generally isn't apparent in the JSON encoding of the numeric value (1.7 is nice and succinct) but manifests in the JSON parsing and intermediate representations on the receiving end. A JSON parsing function would quite reasonably parse 1.7 into an IEEE double precision floating point number. However, finite length / finite precision decimal representations will always run into numbers whose decimal expansions cannot be represented as a finite sequence of digits:

  1. 有理数(例如pi和e)

  1. Irrational numbers (like pi and e)

1.7在以10为基数的表示法中具有有限的表示形式,但是在二进制(以2为基数)的表示法中,不能正确编码1.7.即使二进制数几乎是无限的,您也只会接近1.7,但永远不会精确到1.7.

1.7 has a finite representation in base 10 notation, but in binary (base 2) notation, 1.7 cannot be encoded exactly. Even with a near infinite number of binary digits, you'll only get closer to 1.7, but you'll never get to 1.7 exactly.

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

So, parsing 1.7 into an in-memory floating point number, then printing out the number will likely return something like 1.69 - not 1.7.

JSON 1.7值的使用者可以使用更复杂的技术来解析该值并将其保留在内存中,例如使用具有任意精度的定点数据类型或"string int"数据类型,但这不会完全消除某些数字转换精度下降的幽灵.现实情况是,很少有JSON解析器会受到如此极端的措施的困扰,因为在大多数情况下,这样做的好处很低,而内存和CPU的成本却很高.

Consumers of the JSON 1.7 value could use more sophisticated techniques to parse and retain the value in memory, such as using a fixed-point data type or a "string int" data type with arbitrary precision, but this will not entirely eliminate the specter of loss of precision in conversion for some numbers. And the reality is, very few JSON parsers bother with such extreme measures, as the benefits for most situations are low and the memory and CPU costs are high.

因此,如果您希望将精确的数值发送给使用者,并且不希望将数值自动转换为典型的内部数值表示形式,那么最好的选择是将数值作为字符串发送出去并告诉消费者在需要和何时对其执行数字运算时应如何处理该字符串.

So if you are wanting to send a precise numeric value to a consumer and you don't want automatic conversion of the value into the typical internal numeric representation, your best bet is to ship the numeric value out as a string and tell the consumer exactly how that string should be processed if and when numeric operations need to be performed on it.

例如:在某些JSON生产器中(JRuby,其中之一),BigInteger值自动以字符串形式输出到JSON,这主要是因为BigInteger的范围和精度远大于IEEE双精度浮点数.将BigInteger值减小为两倍以便输出为JSON数字通常会丢失有效数字.

For example: In some JSON producers (JRuby, for one), BigInteger values automatically output to JSON as strings, largely because the range and precision of BigInteger is so much larger than the IEEE double precision float. Reducing the BigInteger value to double in order to output as a JSON numeric will often lose significant digits.

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

Also, the JSON spec (http://www.json.org/) explicitly states that NaNs and Infinities (INFs) are invalid for JSON numeric values. If you need to express these fringe elements, you cannot use JSON number. You have to use a string or object structure.

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

Finally, there is another aspect which can lead to choosing to send numeric data as strings: control of display formatting. Leading zeros and trailing zeros are insignificant to the numeric value. If you send JSON number value 2.10 or 004, after conversion to internal numeric form they will be displayed as 2.1 and 4.

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

If you are sending data that will be directly displayed to the user, you probably want your money figures to line up nicely on the screen, decimal aligned. One way to do that is to make the client responsible for formatting the data for display. Another way to do it is to have the server format the data for display. Simpler for the client to display stuff on screen perhaps, but this can make extracting the numeric value from the string difficult if the client also needs to make computations on the values.

这篇关于为什么要在JSON中使用字符串表示十进制数字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆