Java中浮点数的输出形式及可能引起的问题

类别:Java 点击:0 评论:0 推荐:
近来在项目中使用到了一个数据库SQL语句,这个SQL语句是动态生成的,类似下面的方式:
    Double quantity = ...;
    String sql = "INSERT INTO " + tableName + " (id, name, quantity) VALUES(" 
+ id + ",'" + name + "'," + quantity + ")";

    系统正常运行1年多了,突然近段时间系统出错。由于生产环境缺乏充分的调试信息,所以,调试非常困难。经过艰苦的追踪和调试输出,发现问题出现在Double型的quantity的字符串表示上。因为近期系统中quantity遇到了一个比较大的值(大于了10的7次方),而Double型的quantity这儿解析为了类似“1.153E7”的科学计数法形式,虽然大部分的SQL兼容的驱动器基本都认识这种科学计数法形式的数字表示形式,但还是有一些不支持(是否SQL规范中有规定我不清楚,欢迎大家求证)。对于一些不支持这种数字表示形式的驱动器,问题就出来了,它会把它当成一个非法的数字从而报错。

在Java中浮点数包括基本型float、double,以及对象包装类型的Float和Double,对于这些浮点数的输出,不管是显式地还是隐式地调用toString()得到它的表示字串,输出格式都是按照如下规则进行的:
?     如果绝对值大于0.001、小于10000000,那么就以常规的小数形式表示。
?     如果在上述范围之外,则使用科学计数法表示。即类似于1.234E8的形式。

清楚这些,就可以避免一些问题,另外,对于大多数的企业应用,用户更倾向于使用普通的小数表示形式,而不是科学计数法的表示形式,所以,在实际项目中也经常会遇到需要把Java中浮点数默认的表示形式统一为普通小数形式输出的问题,可以使用java.text.DecimalFormat进行转换,比如,把double型的转换为保留4位小数点输出:

DecimalFormat df = new DecimalFormat("#.0000");
double d = 12345678.12345;
String dStr = df.format(d);


这样dStr就变成了:1234567.1234,而不会是:1.234567812345E7 的形式了。
    
    了解Java中对浮点数的输出表示,并时时熟记于心,尤其对于一些面向普通用户的企业应用中,注意在适当的地方对浮点数进行格式化是非常重要的。对于一些SQL驱动器也要了解是否识别这种科学计数法形式,否则,就等于为系统埋下了一颗不定时的炸弹,什么时候爆炸并不知道,也许是在几年之后,那么在那时寻找问题、修正程序将变得非常困难。

本文地址:http://com.8s8s.com/it/it16162.htm