You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JsonCpp处理uint64范围边界存异常,能否配置验证?

问题

在使用JsonCpp时发现数值触及uint64范围边界时存在异常行为:

  • [0, 2⁶⁴-1]范围内的数值可正常工作;
  • 超出范围但处于[2⁶⁴, 2⁶⁴+2¹¹]区间的数值返回0;
  • 超过2⁶⁴+2¹¹的数值则抛出异常。

请问此现象是否符合预期?能否配置JsonCpp进行这类验证?

复现代码

#include <iostream>
#include <jsoncpp/json/json.h>
#include <jsoncpp/json/reader.h>
#include <jsoncpp/json/value.h>

int main() {
    // std::string uint64Str = "1234"; // 任何[0, 2**64-1]范围内的数值都能正常工作(输出uint64Str)
    // std::string uint64Str = "18446744073709551615"; // [0, 2**64-1]范围内的数值都正常,包括2**64-1(输出uint64Str)
    // std::string uint64Str = "18446744073709551616"; // uint64最大值+1,输出0
    // std::string uint64Str = "18446744073709551617"; // uint64最大值+2,输出0
    // ...
    // std::string uint64Str = "18446744073709553663"; // uint64最大值+2048,输出0
    // std::string uint64Str = "18446744073709553664"; // uint64最大值+2049,输出0
    std::string uint64Str = "18446744073709553665"; // uint64最大值+2050及以上,抛出Json::LogicError异常,信息为"double out of UInt64 range"
    Json::Value root;
    Json::Reader reader;
    bool parsingResult = reader.parse("{\"key\":"+uint64Str+"}", root);
    std::cout<<root["key"].asUInt64()<<std::endl;
    
    return 0;
}
回答

现象是否符合预期?

这个现象是JsonCpp内部实现逻辑导致的,但并非设计上的预期行为,本质是浮点数精度丢失引发的边界问题:

  • JsonCpp默认将JSON数值解析为double类型,而double仅能精确表示2⁵³以内的整数。对于超过2⁵³的整数,double无法精准存储,会出现舍入。
  • 当数值处于[2⁶⁴, 2⁶⁴+2¹¹]区间时,double存储后转换回uint64会触发溢出,最终返回0;当数值超过2⁶⁴+2¹¹时,double的表示会超出uint64的可转换范围,触发显式的范围检查,抛出异常。

能否配置JsonCpp进行这类验证?

可以通过配置解析器开启严格的数值范围验证,避免模糊行为:

  1. 弃用已过时的Json::Reader,改用Json::CharReaderBuilder,并开启严格模式:
    Json::CharReaderBuilder builder;
    builder["collectComments"] = false;
    // 开启严格数值范围检查
    builder["strictMode"] = true;
    std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
    std::string errors;
    std::string jsonStr = "{\"key\":" + uint64Str + "}";
    bool parsingResult = reader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.size(), &root, &errors);
    
  2. 开启strictMode后,任何超出uint64范围的数值在解析阶段就会直接抛出异常,不会出现返回0的情况。
  3. 另外,部分新版本的JsonCpp支持将数值直接解析为uint64_t类型(而非默认double),需确保JSON数值类型明确,并配置对应解析选项。

内容的提问来源于stack exchange,提问作者Danny Cohen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 03:44:55