`

json-lib对于浮点数出现精度问题

    博客分类:
  • json
阅读更多
项目使用json-lib-2.4-jdk15.jar进行json<->pojo之间转换,今天发现一个悲剧问题:
String jsonString = "[{\"amount\":670526.32},{\"amount\":29473.68}]";
JSONObject jsonObject = JSONObject.fromObject(jsonString);

结果发现第一个数值转换后为670526.3,精度出现问题,网上搜索一番,没找到原因,蛮试试降低版本json-lib-2.3-jdk15.jar,竟然正确,看来这小版本变动大有文章,反编译看源码,先看看2.4的
JSONObject.java
private static JSONObject _fromJSONTokener(JSONTokener tokener, JsonConfig jsonConfig)
  {
......
v = tokener.nextValue(jsonConfig);
......
}

JSONTokener.java
public Object nextValue(JsonConfig jsonConfig)
  {
......
if (((b >= '0') && (b <= '9')) || ((((b == '.') || (b == '-') || (b == '+'))) && ((
      (b != '0') || (
      (s.length() > 2) && (((s.charAt(1) == 'x') || (s.charAt(1) == 'X'))))))));
    try
    {
      return new Integer(Integer.parseInt(s.substring(2), 16));
    }
    catch (Exception e)
    {
      try
      {
        return new Integer(Integer.parseInt(s, 8));
      }
      catch (Exception e)
      {
        try
        {
          return NumberUtils.createNumber(s);
        } catch (Exception e) {
          return s;
        }

        if ((JSONUtils.isFunctionHeader(s)) || (JSONUtils.isFunction(s)))
          return s;
      }
......
}

NumberUtils.java
  public static Number createNumber(String str)
    throws NumberFormatException
  {
......
try
    {
      return createInteger(str);
    }
    catch (NumberFormatException allZeros)
    {
      try {
        return createLong(str);
      }
      catch (NumberFormatException nfe)
      {
        return createBigInteger(str);
      }

      boolean allZeros = (isAllZeros(mant)) && (isAllZeros(exp));
      try {
        Float f = createFloat(str);
        if ((!(f.isInfinite())) && (((f.floatValue() != 0.0F) || (allZeros))))
          return f;
      }
      catch (NumberFormatException nfe)
      {
      }
      try {
        Double d = createDouble(str);
        if ((!(d.isInfinite())) && (((d.doubleValue() != 0.0D) || (allZeros))))
          return d;
      }
      catch (NumberFormatException d)
      {
      }
    }
    return createBigDecimal(str);
}

以上看出,对于浮点数字,会先使用createFloat()进行转换,此处也是导致精度出现问题的关键
2.3代码:
JSONTokener.java
public Object nextValue(JsonConfig jsonConfig)
  {
......
if (((b >= '0') && (b <= '9')) || ((((b == '.') || (b == '-') || (b == '+'))) && ((
      (b != '0') || (
      (s.length() > 2) && (((s.charAt(1) == 'x') || (s.charAt(1) == 'X'))))))));
    try
    {
      return new Integer(Integer.parseInt(s.substring(2), 16));
    }
    catch (Exception e)
    {
      try
      {
        return new Integer(Integer.parseInt(s, 8));
      }
      catch (Exception e)
      {
        try
        {
          return new Integer(s);
        } catch (Exception e) {
          try {
            return new Long(s);
          } catch (Exception f) {
            try {
              return new Double(s);
            } catch (Exception g) {
              return s;
            }

            if ((JSONUtils.isFunctionHeader(s)) || (JSONUtils.isFunction(s)))
              return s;
          }
}

以上看出,对于浮点数字,会先使用new Double(s)

最后写个main函数测试:
String a = "670526.01";
System.out.println("aa:"+Float.valueOf(a));
System.out.println("aa:"+new Double(a));

打印结果:
aa:670526.3
aa:670526.32

小版本的差异,出现了如此差异,实在不知说什么好。
目前只能降低版本,不过要多做测试;还有一种方法,全部使用字符串,如String jsonString = "[{\"amount\":\"670526.32\"},{\"amount\":\"29473.68\"}]";
分享到:
评论

相关推荐

    JSON Java:Json-lib+依赖包+示例

    Json-lib不仅支持基本的Java类型,如字符串、整数、浮点数和布尔值,还支持复杂的对象和集合。 该压缩包包含以下文件: 1. `json-lib-2.4-jdk15.jar`:这是Json-lib的核心库,包含了处理JSON的主要类和方法。 2. `...

    json-c 一个用于c语言的json解析库,很强大

    3. **动态类型系统**:JSON-c库允许JSON对象中的值是动态的,可以是整数、浮点数、字符串、布尔值、JSON对象或JSON数组,这与JSON的标准完全兼容。 4. **递归深度控制**:为了避免无限递归导致的栈溢出,`json-c`...

    关于浮点数的精度问题

    浮点数精度问题是一个经典的问题,对于了解和学习C语言有一定帮助。浮点数的精度问题是由于计算机对浮点数的存储方式和表示方法所致。 IEEE754 的浮点数存储格式对浮点数的表示方法进行了规定。浮点数可以分为三...

    S7-200PLC双精度浮点数转换为整形.pdf

    2. 双精度浮点数与PLC的数据处理能力:流量仪表等智能设备通常使用双精度浮点数存储数据,但由于S7-200 PLC只能处理单精度浮点数,因此无法直接使用这些双精度仪表数据,这限制了PLC进一步的数据处理及应用。...

    S7-200SMART_双精度浮点数转换为单精度浮点数库文件及使用说明.rar

    因此,对于双精度浮点数的处理,通常需要通过软件库或者自定义算法来实现转换。 3. **库文件介绍**: 提供的库文件是专门针对S7-200SMART设计的,用于实现双精度浮点数到单精度浮点数的转换。该库可能包含了一系列...

    JSON-C库的源码

    文章提到作者尝试过多种C++的JSON库,如JsonCPP、QJson、Json-Spirit 和 jaula 等,但这些库存在各种问题,例如不支持中文(即使是UTF-8编码)、难以在Windows环境下编译或体积过大等问题。 最终,作者选择了C语言...

    TIA博途-截取浮点数-自定义小数位数-全局FC库文件-V17版本-GF-截取浮点数-自定义小数点后位数.zip

    总之,TIA博途中的全局FC库文件“GF_截取浮点数_自定义小数点后位数”提供了一种高效且灵活的方式来处理浮点数的格式化问题。通过自定义小数位数,用户可以根据具体需求调整数值的精度,简化了编程过程,提高了代码...

    S7-200双精度浮点数转单精度浮点数例程

    本代码将双精度浮点数转换为单精度浮点数,适合浮点数为正值的转换。 使用后将占用VD2810~VD2970字节,欢迎交流。 本代码的完成经历了一段时间的刻苦研究,无偿提供给真正需要的人,希望同行少走弯路。 代码允许复制...

    TIA博途-32位浮点数大小端存储-高低字节转换的具体方法示例(4种字节排列顺序).docx

    在TIA博途中,理解和掌握这些概念对于正确处理数据传输和程序设计至关重要。 首先,我们要理解大端字节序和小端字节序的基本原理。在大端字节序中,最高有效字节存储在最低地址,而小端字节序则相反,最低有效字节...

    对S7-200PLC双精度浮点数转单精度浮点数例程的一点补充

    本篇文章主要探讨了如何在S7-200 PLC中处理双精度浮点数转换为单精度浮点数的问题,这对于管理智能电表、远传水表等远程抄表系统的数据一致性至关重要。双精度浮点数提供了更高的精度,但在处理能力有限的S7-200 PLC...

    JSON-c语言开发指南

    JSON格式简洁紧凑,对比XML,它在处理大量数据时具有更高的效率,并且避免了不同浏览器解析XML DOM时可能出现的兼容性问题。 JSON的基本结构包含两种类型: 1. "名称/值"对的集合,这在许多语言中被视为对象、纪录...

    c语言浮点数高精度加法计算

    c语言浮点数高精度加法计算

    关于FD-ASM51浮点数格式的说明

    FD-ASM51浮点数的数学表示为a×2b,其中a为尾数,b为阶码。3字节浮点数共3字节,第1字节表示数符和阶码,

    TIA博途-32位浮点数大小端存储-高低字节转换全局FB库文件(4种字节排列顺序)-V17版本.zip

    计算机内部是以二进制形式存储数据的,对于多字节的数据类型(如32位浮点数),其字节的排列顺序有两种方式:大端模式(Big-Endian)和小端模式(Little-Endian)。大端模式是指最高有效字节(也称为高字节或MSB,...

    IEEE-754标准 定义浮点数转换工具

    - 步骤3:指数计算,确定指数值,并考虑偏移量(例如,对于双精度,偏移量是1023)。 - 步骤4:尾数转换,将尾数转换为二进制。 - 步骤5:处理特殊情况,如无穷大、NaN(非数字)等。 #### 3.2 IEEE-754到十进制 -...

    DSP系统实验02New-定点和浮点数格式汇总.pptx

    DSP系统实验02New-定点和浮点数格式汇总.pptx

    浮点数(单精度浮点数,双精度浮点数)

    浮点数(单精度浮点数,双精度浮点数) 浮点数是一种数字表示方法,用于近似表示任意实数。在计算机中,浮点数由一个整数或定点数(即尾数)乘以某个基数(通常是 2)的整数次幂得到。这种表示方法类似于基数为 10 ...

    16进制浮点数-10进制浮点数的数据转换

    1. IEEE 754标准:这是计算机中广泛使用的浮点数表示标准,包括单精度(32位)和双精度(64位)格式。 2. 单精度浮点数:32位,分为三个字段:符号位(1位)、指数位(8位)和尾数位(23位)。16进制示例:0x41C...

    AB-Micro系列PLC双精度浮点数转换为整形.pdf

    它能够确保通讯信息的准确性,避免了因PLC停电或精度问题导致的累计误差,大大提高了数据的一致性。这意味着,诸如流量计等仪表的累计信息,可以通过PLC直接读取,并且用于现场人机界面显示或远程传输,降低了现场...

    BAT批处理学习-数值计算-计算正浮点数的和.cmd.zip

    因此,对于高精度要求的浮点数运算,可能需要寻找更专业的脚本语言或者编程语言来实现。 总结来说,批处理脚本虽然在处理浮点数上存在局限性,但通过巧妙的技巧和外部工具,我们仍然可以实现基本的浮点数运算。这个...

Global site tag (gtag.js) - Google Analytics