////
Copyright (c) 2020 Krystian Stasiowski (sdkrystian@gmail.com)
Copyright (c) 2025 Dmitry Arkhipov (grisumbras@yandex.ru)

Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

Official repository: https://github.com/boostorg/json
////

[#dom_numbers]
= 数字 JSON数字使用`std::int64_t`、`std::uint64_t`和`double`表示。当 &lt;<ref_value>&gt; 从无符号整数构造时，其&lt;<ref_kind>&gt;将为`kind::uint64`。同样，从有符号整数构造的&lt;<ref_value>&gt; 将具有`kind::int64`，若从浮点类型构造则为`kind::double_`：</ref_value></ref_kind></ref_value>

[source]
----
include::../../../test/doc_using_numbers.cpp[tag=doc_using_numbers_1,indent=0]
----

访问&lt;<ref_value>&gt;内包含的数字时，所使用的函数必须与该值的&lt;<ref_kind>&gt;完全匹配；不会执行任何转换。例如，如果在一个包含`std::uint64_t` 的 &lt;<ref_value>&gt; 上调用 `as_double`，将抛出异常。类似地，函数 `if_double` 将返回`nullptr`，而调用 `get_double` 将导致未定义行为：</ref_value></ref_kind></ref_value>

[source]
----
include::../../../test/doc_using_numbers.cpp[tag=doc_using_numbers_2,indent=0]
----

若已知 &lt;<ref_value>&gt; 包含数字，但不确定其 &lt;<ref_kind>&gt;，可使用 `value::to_number` 将该&lt;<ref_value>&gt; 转换为算术类型：</ref_value></ref_kind></ref_value>

[source]
----
include::../../../test/doc_using_numbers.cpp[tag=doc_using_numbers_3,indent=0]
----

若&lt;<ref_value>&gt;不包含数字，或当转换目标为整数类型`T`且数字无法被`T`精确表示时，将导致转换失败。否则，结果是通过`static_cast`将数字转换为`T`所得的值：</ref_value>

[source]
----
include::../../../test/doc_using_numbers.cpp[tag=doc_using_numbers_4,indent=0]
----

在无法使用异常的场合，可改用接受{ref_error_code}的`value::to_number`重载，其语义与抛出异常版本完全相同：

[source]
----
include::../../../test/doc_using_numbers.cpp[tag=doc_using_numbers_5,indent=0]
----

在解析 JSON 文档时，数字的表示类型并未显式指定，而必须根据其值来确定。通常，解析器会选择能够精确存储文档中所出现数字的最佳类型。对于整数（即不带小数部分或指数的数字），若其值无法用 `std::uint64_t` 或 `std::int64_t` 表示，则会以 `double` 类型存储，以保留其数量级。

[source]
----
include::../../../test/doc_using_numbers.cpp[tag=doc_using_numbers_6,indent=0]
----

更正式地，如果该数字：

* 包含小数点，或
* 包含指数，或
* 为负数且其值小于`INT64_MIN`，或
* 为正数且其值大于`UINT64_MAX`，

则其类型为`double`。否则，若数字为正数且其值大于`INT64_MAX`，则其类型为`std::uint64_t`。其余所有数字均被解析为`std::int64_t`。
