JAVA 精确计算时的陷阱
troy
在java.math包中有个BigDecimal类,通过这个类可以进行精确计算. 我们知道BigDecimal有个setScale(int 精度,int 舍入模式)方法,随之而来问题出现了,当运行如下代码时:
/**
* @author troy(J2EE)
* @version 1.0
*/
import java.math.*;
public class Test{
public static void main(String[] args){
//精度为2,四舍五入模式
BigDecimal a =new BigDecimal(0.825).setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(a);
}
}
却惊奇地打印出结果:
0.82
Oh My God,对0.825进行小数点后保留2位有效数字,四舍五入后结果应该是:0.83。为什么打印结果是0.82?
没错BigDecimal(double val)这个构造器欺骗了我们,它使用了0.825的近似值(0.8249999999999……)来构造BigDecimal。
为什么会这样?
原来JAVA存储浮点数(float、double)时,使用的是IEEE754标准,每个浮点数使用的是 符号位、阶码、尾数来表示:
````````符号位 阶码 尾数 长度
float 1 8 23 32
double 1 11 52 64
通过这种方法保存在计算机里面的浮点数,实际上是它的近似值。举例说明问题:
定义一个double 38414.4,将它转换为16进制。我们先计算整数部分38414等于960E。小数处理:0.4=0*0.5+0.25*1+0.0625*0+……,实际上我们永远计算不完。
结论:当我们定义一个浮点数时,请告诉自己,我们定义只不过是这个浮点数的近似值,即0.825!=0.825。
为了避免这个问题,我们应该使用如下方法:
/**
* @author troy(J2EE)
* @version 1.0
*/
import java.math.*;
public class Test{
public static void main(String[] args){
BigDecimal a =new BigDecimal("0.825").setScale(2, BigDe
相关文档:
使用java中的动态代理可以完成很多事情,比如将业务实例进行托管,实现AOP等,但是Php中没有实现这样的东西,昨天突然想到其实可以通过eval来模拟一个动态代理机制。php比java不同的是,php是不需要编译的,因此只要我们能够动态生成一段代码,然后用eval来执行就可以达到效果。代码如下:
/**
* 代理实现类
*/
inter ......
package org.rut.util.algorithm.support;
import org.rut.util.algorithm.SortUtil;
/**
* @author treeroot
* @since 2006-2-2
* @version 1.0
*/
public class InsertSort implements SortUtil.Sort{
/* (non-Javadoc)
* ......
Java反编译工具Eclipse插件--Jode Decompiler
安装非常的简单:
help => Software Updates => Find and Install... => Search for new features to install,
单击"New Remote Site..." 在URL栏输入 http://www.technoetic.com/eclipse/update ,
然后下一步,就可以看到“j ......
单态定义:
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
Singleton模式就为我们提供了这样实现的可能。使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage c ......