zbb1990

导航

BigDecimal 比较大小

在模拟hibernate完成sql语句的组装的时候,在java类型与数据库类型之间,规定只允许三种类型,日期型对应java.util.Date,数字型对应java.math.BigDecimal,字符型对应java.lang.String。在处理BigDecimal的时候,发现了一些有趣的现象。

  • 大小比较:通常我们比较两个对象是否相等的时候,首先考虑的就是equals方法了。但是,在BigDecimal里面,这个就行不通了。比如:

    java 代码
    1. BigDecimal b1=new BigDecimal("1.0");   
    2. BigDecimal b2=new BigDecimal("1.00");   
    3. boolean t=b1.equals(b2);  


    怎么样,你认为t是true还是false?它还真是false。BigDecimal的大小比较,1.0与1.00是不相等的,得采用它自带的compareTo方法:
      

    java 代码
    1. int i=b1.compareTo(b2)  


    这一次,返回的i可能为-1、0、1,分别表示小于、等于、大于

  • 构造函数:解决了上面这个问题好像万事大吉了,结果,我在做测试的时候,又发现了一个莫名其妙的问题,代码如下:

java 代码
  1. BigDecimal bd=supplierRecentProductDao.findHistoryReturnRate("001""001");   
  2. assertEquals(bd.compareTo(new BigDecimal(0.15)),0);  


计算得到的bd值就是0.15,但是测试它偏偏告诉我:

java 代码
  1. junit.framework.AssertionFailedError: expected:<1> but was:<0>   

加上打印语句一看:

java 代码
  1. System.out.println("HistoryReturnRate:"+bd+","+new BigDecimal(0.15));  


发现结果是这样的:

java 代码
  1. HistoryReturnRate:0.150000,0.1499999999999999944488848768742172978818416595458984375  

我们的 new BigDecimal(0.15)得到了一个超接近的数“0.1499999999999999944488848768742172978818416595458984375”,但它就是小于0.15。上网查得,BigDecimal有三种构造方式

java 代码
  1. BigDecimal(Stirng s),   
  2. BigDecimal(int i,int k),   
  3. BigDecimal(double d)  

,由于浮点运算的原因,要慎用第三种方式,否则就会得到上面的结果。所以,改用

java 代码
  1. assertEquals(bd.compareTo(new BigDecimal("0.15")),0);  

之后,测试顺利通过了。

2012-11-07 14:51:00 

posted on 2012-11-07 14:53  zbb1990  阅读(4232)  评论(0编辑  收藏  举报