项目使用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 的浮点数存储格式对浮点数的表示方法进行了规定。浮点数可以分为三...
TIA博途-32位浮点数大小端存储-高低字节转换的具体方法示例(4种字节排列顺序)
因此,对于双精度浮点数的处理,通常需要通过软件库或者自定义算法来实现转换。 3. **库文件介绍**: 提供的库文件是专门针对S7-200SMART设计的,用于实现双精度浮点数到单精度浮点数的转换。该库可能包含了一系列...
本代码将双精度浮点数转换为单精度浮点数,适合浮点数为正值的转换。 使用后将占用VD2810~VD2970字节,欢迎交流。 本代码的完成经历了一段时间的刻苦研究,无偿提供给真正需要的人,希望同行少走弯路。 代码允许复制...
计算机内部是以二进制形式存储数据的,对于多字节的数据类型(如32位浮点数),其字节的排列顺序有两种方式:大端模式(Big-Endian)和小端模式(Little-Endian)。大端模式是指最高有效字节(也称为高字节或MSB,...
c语言浮点数高精度加法计算
#资源达人分享计划#
FD-ASM51浮点数的数学表示为a×2b,其中a为尾数,b为阶码。3字节浮点数共3字节,第1字节表示数符和阶码,
DSP系统实验02New-定点和浮点数格式汇总.pptx
对S7-200PLC双精度浮点数转单精度浮点数例程的一点补充,远程抄表相关技术的交流
1. IEEE 754标准:这是计算机中广泛使用的浮点数表示标准,包括单精度(32位)和双精度(64位)格式。 2. 单精度浮点数:32位,分为三个字段:符号位(1位)、指数位(8位)和尾数位(23位)。16进制示例:0x41C...
浮点数(单精度浮点数,双精度浮点数) 浮点数是一种数字表示方法,用于近似表示任意实数。在计算机中,浮点数由一个整数或定点数(即尾数)乘以某个基数(通常是 2)的整数次幂得到。这种表示方法类似于基数为 10 ...
因此,对于高精度要求的浮点数运算,可能需要寻找更专业的脚本语言或者编程语言来实现。 总结来说,批处理脚本虽然在处理浮点数上存在局限性,但通过巧妙的技巧和外部工具,我们仍然可以实现基本的浮点数运算。这个...
直接下载,电脑运行,加入了浮点数的简易计算机,是本篇笔记编译的程序
符合IEEE-754标准的单精度浮点形数据,C51里用4字节存储一个浮点数,如用0x3F000000表示小数0.5;0xBDCCCCCD表示小数-0.1。一般我们还是习惯用十进制来表示容易看。但有的时候我们需要知道一个十进制的小数保存到...
总之,TIA博途中的全局FC库文件“GF_截取浮点数_自定义小数点后位数”提供了一种高效且灵活的方式来处理浮点数的格式化问题。通过自定义小数位数,用户可以根据具体需求调整数值的精度,简化了编程过程,提高了代码...
- 步骤3:指数计算,确定指数值,并考虑偏移量(例如,对于双精度,偏移量是1023)。 - 步骤4:尾数转换,将尾数转换为二进制。 - 步骤5:处理特殊情况,如无穷大、NaN(非数字)等。 #### 3.2 IEEE-754到十进制 -...
学习计算机组成原理时实现的IEEE754标准的浮点数的机器数转换器,只要填入十进制浮点数值,便可以求出单精度的IEEE754标准的机器数表示方法,反之,给出IEEE754的机器数,可以求出其对应的十进制浮点数值