当前位置: 首页 > 面试题库 >

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

林丁雷
2023-03-14
问题内容

一些API(例如paypal
API)
在JSON中使用字符串类型表示十进制数字。所以"7.47"代替7.47

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


问题答案:

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

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

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

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

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

因此,将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和Infinities(INF)对于JSON数值无效。如果需要表达这些边缘元素,则不能使用JSON数字。您必须使用字符串或对象结构。

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

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



 类似资料:
  • 问题内容: 我写了一些代码将十六进制显示字符串转换为十进制整数。但是,当输入类似100a或625b(带有字母的东西)时,我得到了这样的错误: java.lang.NumberFormatException:对于输入字符串:java.lang.Integer.parseInt(未知源)处的java.lang.NumberFormatException.forInputString(未知源)处为“ 1

  • 我正在写一个Rust程序,读取I2C总线并保存数据。当我读取I2C总线时,我会得到十六进制值,比如,,等等。 现在,我只能将其作为字符串处理并按原样保存。有没有办法把它解析成一个整数?它有内置的功能吗?

  • 我有十六进制字符串,例如“0x103E”,我想将其转换为整数。意思是to我尝试了但它给出了数字格式异常。我如何实现这一点?

  • 我有一个像“示例”这样的字符串。我想得到十六进制格式的字符串;像这样: 请给出C#语法。

  • 问题内容: 有时,我看到用十六进制而不是十进制数字定义的整数常量。这是我从GL10类中学到的一小部分: 显然,用而不是定义起来更简单,那么也许会有一些性能提升吗?我绝对不这么认为,因为那以后更改它应该是编译器的工作。 问题答案: 可能是为了组织和视觉上的清洁。基数16与二进制的关系比基数10更简单,因为在基数16中,每个数字正好对应于四个位。 请注意,在上述常量中,常量是如何与许多数字组合在一起的

  • 问题内容: 我想将十六进制字符串转换为二进制字符串。例如,十六进制2是0010。下面是代码: 但是,这仅适用于十六进制0-9;它不适用于十六进制A-F,因为它使用。谁能增强它? 问题答案: 您需要告诉Java int是十六进制的,如下所示: