• 测试技术
  • 博客
  • 视频
  • 开源
  • 论坛
  • 沙龙
  • 下载
  • 杂志
  • 招聘

字号: | 推荐给好友 上一篇 | 下一篇

使用浮点数和小数中的技巧和陷阱

发布: 2008-9-09 09:05 | 作者: 不详 | 来源: 领测软件测试网采编 | 查看: 92次 | 进入领测软件测试网论坛讨论

领测软件测试网

1BDH~ DJ 软件测试技术第一门户G5cT7_/xW!H.^3L

用于较小数的 BigDecimal软件测试技术第一门户R4n%w0X6Ac.H

yp$vL m N从 JDK 1.3 起,Java 开发人员就有了另一种数值表示法来表示非整数: BigDecimal 。 BigDecimal 是标准的类,在编译器中不需要特殊支持,它可以表示任意精度的小数,并对它们进行计算。在内部,可以用任意精度任何范围的值和一个换算因子来表示 BigDecimal ,换算因子表示左移小数点多少位,从而得到所期望范围内的值。因此,用 BigDecimal 表示的数的形式为 unscaledValue*10 -scale 。软件测试技术第一门户1e!~3NN(^7U-RrYR1b+I

6KW:JH0B)R"j^]v用于加、减、乘和除的方法给 BigDecimal 值提供了算术运算。由于 BigDecimal 对象是不可变的,这些方法中的每一个都会产生新的 BigDecimal 对象。因此,因为创建对象的开销, BigDecimal 不适合于大量的数学计算,但设计它的目的是用来精确地表示小数。如果您正在寻找一种能精确表示如货币量这样的数值,则 BigDecimal 可以很好地胜任该任务。

8L A [%R dGZ 软件测试技术第一门户,?g#TYH9}

所有的 equals 方法都不能真正测试相等软件测试技术第一门户+Yix8VY~

软件测试技术第一门户*ijI;M5n+S"U

如浮点类型一样, BigDecimal 也有一些令人奇怪的行为。尤其在使用 equals() 方法来检测数值之间是否相等时要小心。 equals() 方法认为,两个表示同一个数但换算值不同(例如, 100.00 和 100.000 )的 BigDecimal 值是不相等的。然而, compareTo() 方法会认为这两个数是相等的,所以在从数值上比较两个 BigDecimal 值时,应该使用 compareTo() 而不是 equals() 。软件测试技术第一门户4u5d0v&~Ez7B S

软件测试技术第一门户"y F)\PhK/Y

另外还有一些情形,任意精度的小数运算仍不能表示精确结果。例如, 1 除以 9 会产生无限循环的小数 .111111... 。出于这个原因,在进行除法运算时, BigDecimal 可以让您显式地控制舍入。 movePointLeft() 方法支持 10 的幂次方的精确除法。软件测试技术第一门户}.[ c{7Q+Ix4j

4H5KV7L7w6k使用 BigDecimal 作为互换类型软件测试技术第一门户^:ljk#TL

T7C6p YZFcSQL-92 包括 DECIMAL 数据类型,它是用于表示定点小数的精确数字类型,它可以对小数进行基本的算术运算。一些 SQL 语言喜欢称此类型为 NUMERIC 类型,其它一些 SQL 语言则引入了 MONEY 数据类型,MONEY 数据类型被定义为小数点右侧带有两位的小数。

,|G%fDa } 软件测试技术第一门户q ^+Mw'@)aU

如果希望将数字存储到数据库中的 DECIMAL 字段,或从 DECIMAL 字段检索值,则如何确保精确地转换该数字?您可能不希望使用由 JDBC PreparedStatement 和 ResultSet 类所提供的 setFloat() 和 getFloat() 方法,因为浮点数与小数之间的转换可能会丧失精确性。相反,请使用 PreparedStatement 和 ResultSet 的 setBigDecimal() 及 getBigDecimal() 方法。软件测试技术第一门户)EY8i+x9qHE

软件测试技术第一门户HM5T2Bo+Y"]

对于 BigDecimal ,有几个可用的构造函数。其中一个构造函数以双精度浮点数作为输入,另一个以整数和换算因子作为输入,还有一个以小数的 String 表示作为输入。要小心使用 BigDecimal(double) 构造函数,因为如果不了解它,会在计算过程中产生舍入误差。请使用基于整数或 String 的构造函数。

K^i6c!N-a

8C+_})c ` GG构造 BigDecimal 数

-y[k E*o:`&wK.S,S

&C:h9N`f#A2Z-^对于 BigDecimal ,有几个可用的构造函数。其中一个构造函数以双精度浮点数作为输入,另一个以整数和换算因子作为输入,还有一个以小数的 String 表示作为输入。要小心使用 BigDecimal(double) 构造函数,因为如果不了解它,会在计算过程中产生舍入误差。请使用基于整数或 String 的构造函数。软件测试技术第一门户~)f(h^kI

"@%H ha#rMAF,t如果使用 BigDecimal(double) 构造函数不恰当,在传递给 JDBC setBigDecimal() 方法时,会造成似乎很奇怪的 JDBC 驱动程序中的异常。例如,考虑以下 JDBC 代码,该代码希望将数字 0.01 存储到小数字段:

lB pBh%}$x&{ 软件测试技术第一门户{3Fv