项目使用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-lib不仅支持基本的Java类型,如字符串、整数、浮点数和布尔值,还支持复杂的对象和集合。 该压缩包包含以下文件: 1. `json-lib-2.4-jdk15.jar`:这是Json-lib的核心库,包含了处理JSON的主要类和方法。 2. `...
3. **动态类型系统**:JSON-c库允许JSON对象中的值是动态的,可以是整数、浮点数、字符串、布尔值、JSON对象或JSON数组,这与JSON的标准完全兼容。 4. **递归深度控制**:为了避免无限递归导致的栈溢出,`json-c`...
浮点数精度问题是一个经典的问题,对于了解和学习C语言有一定帮助。浮点数的精度问题是由于计算机对浮点数的存储方式和表示方法所致。 IEEE754 的浮点数存储格式对浮点数的表示方法进行了规定。浮点数可以分为三...
2. 双精度浮点数与PLC的数据处理能力:流量仪表等智能设备通常使用双精度浮点数存储数据,但由于S7-200 PLC只能处理单精度浮点数,因此无法直接使用这些双精度仪表数据,这限制了PLC进一步的数据处理及应用。...
因此,对于双精度浮点数的处理,通常需要通过软件库或者自定义算法来实现转换。 3. **库文件介绍**: 提供的库文件是专门针对S7-200SMART设计的,用于实现双精度浮点数到单精度浮点数的转换。该库可能包含了一系列...
文章提到作者尝试过多种C++的JSON库,如JsonCPP、QJson、Json-Spirit 和 jaula 等,但这些库存在各种问题,例如不支持中文(即使是UTF-8编码)、难以在Windows环境下编译或体积过大等问题。 最终,作者选择了C语言...
总之,TIA博途中的全局FC库文件“GF_截取浮点数_自定义小数点后位数”提供了一种高效且灵活的方式来处理浮点数的格式化问题。通过自定义小数位数,用户可以根据具体需求调整数值的精度,简化了编程过程,提高了代码...
本代码将双精度浮点数转换为单精度浮点数,适合浮点数为正值的转换。 使用后将占用VD2810~VD2970字节,欢迎交流。 本代码的完成经历了一段时间的刻苦研究,无偿提供给真正需要的人,希望同行少走弯路。 代码允许复制...
在TIA博途中,理解和掌握这些概念对于正确处理数据传输和程序设计至关重要。 首先,我们要理解大端字节序和小端字节序的基本原理。在大端字节序中,最高有效字节存储在最低地址,而小端字节序则相反,最低有效字节...
本篇文章主要探讨了如何在S7-200 PLC中处理双精度浮点数转换为单精度浮点数的问题,这对于管理智能电表、远传水表等远程抄表系统的数据一致性至关重要。双精度浮点数提供了更高的精度,但在处理能力有限的S7-200 PLC...
JSON格式简洁紧凑,对比XML,它在处理大量数据时具有更高的效率,并且避免了不同浏览器解析XML DOM时可能出现的兼容性问题。 JSON的基本结构包含两种类型: 1. "名称/值"对的集合,这在许多语言中被视为对象、纪录...
c语言浮点数高精度加法计算
FD-ASM51浮点数的数学表示为a×2b,其中a为尾数,b为阶码。3字节浮点数共3字节,第1字节表示数符和阶码,
计算机内部是以二进制形式存储数据的,对于多字节的数据类型(如32位浮点数),其字节的排列顺序有两种方式:大端模式(Big-Endian)和小端模式(Little-Endian)。大端模式是指最高有效字节(也称为高字节或MSB,...
- 步骤3:指数计算,确定指数值,并考虑偏移量(例如,对于双精度,偏移量是1023)。 - 步骤4:尾数转换,将尾数转换为二进制。 - 步骤5:处理特殊情况,如无穷大、NaN(非数字)等。 #### 3.2 IEEE-754到十进制 -...
DSP系统实验02New-定点和浮点数格式汇总.pptx
浮点数(单精度浮点数,双精度浮点数) 浮点数是一种数字表示方法,用于近似表示任意实数。在计算机中,浮点数由一个整数或定点数(即尾数)乘以某个基数(通常是 2)的整数次幂得到。这种表示方法类似于基数为 10 ...
1. IEEE 754标准:这是计算机中广泛使用的浮点数表示标准,包括单精度(32位)和双精度(64位)格式。 2. 单精度浮点数:32位,分为三个字段:符号位(1位)、指数位(8位)和尾数位(23位)。16进制示例:0x41C...
它能够确保通讯信息的准确性,避免了因PLC停电或精度问题导致的累计误差,大大提高了数据的一致性。这意味着,诸如流量计等仪表的累计信息,可以通过PLC直接读取,并且用于现场人机界面显示或远程传输,降低了现场...
因此,对于高精度要求的浮点数运算,可能需要寻找更专业的脚本语言或者编程语言来实现。 总结来说,批处理脚本虽然在处理浮点数上存在局限性,但通过巧妙的技巧和外部工具,我们仍然可以实现基本的浮点数运算。这个...