我有两种互相矛盾的心态:
心态1:
JSON 数字始终是双精度浮点数。因此:
1
和之间没有语义差异1.0
- 都代表完全相同的数字;12345678901234567890
其实是12345678901234567000
因为12345678901234567890
无法准确表示为双精度浮点数。
心态2:
JSON 数字不能总是被解释为双精度浮点数。JSON 是一种不同于 JavaScript 的通信协议。认为 JSON 数字总是双精度浮点数的观点源于 JavaScript 和 JSON 之间的混淆,以及 JavaScript 中默认 JSON 解析器和序列化器的特性,它们以这种方式解释它们。因此:
1
和1.0
不必相同。具体来说,尾随的有.0
无可用于编码类型信息。许多编程语言(如 Java 或 C#)区分整数和浮点数。要求这些语言中的整数必须始终不带尾随 进行序列化.0
,而浮点数必须始终带尾随 进行序列化.0
,这是合理的。12345678901234567890
和12345678901234567000
不是相同的数字。某些广泛使用的解析器默认将它们解释为相同的数字,因为它们将 JSON 数字强制转换为双精度浮点数 - 但这是这些解析器的问题,而不是 JSON 本身的问题。
这两种心态,如果有的话,哪一种是正确的呢?
谷歌搜索似乎得出了相互矛盾的结果。
- https://json-schema.org/understanding-json-schema/reference/numeric表示:“ JSON 没有整数和浮点值的不同类型。因此,小数点的存在或不存在不足以区分整数和非整数。例如,1 和 1.0 是在 JSON 中表示相同值的两种方式。 ” - 所以看起来这与心态 1 一致;
- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON讨论了使用 JSON 序列化和反序列化不能存储为双精度浮点数的大数 - 因此它似乎与 Mindset 2 一致。
JSON 格式对其可以表示的数字没有限制:以下 JSON 是有效的:
...即使它所代表的数字远远超出了双精度浮点数的容量。
类似地,您可以获得以下有效的 JSON:
...尽管双精度浮点数无法表示那么多有效数字。
这些问题不是 JSON 格式所固有的,而是读写 JSON 的实现所固有的。RFS 8259标准在第 6 节关于数字的部分中提到了这一点:
这意味着你引用的第一篇文章并不完全准确。即“小数点的存在与否不足以区分整数和非整数”的说法。
虽然在实践中这可能是真的,但这确实是一个实现方面的问题。我们可以想象,在实现中,区分整数和非整数就足够了。这不是 JSON 格式本身的事。