zoukankan      html  css  js  c++  java
  • Java 数值计算精度问题

      最近刚好做到涉及金额方面的项目,不像普通in,double,floatt类型来修饰,而是用BigDecimal来修饰,就去收集下了这方面的资料,整理如下:

    1、float和double只能用来做科学计算或者是工程计算,在广域数值范围上提供较为精确的快速近似计算;而在商业计算要求结果精确(比如,有的编程语言中提供了专门的货币类型来处理),所以Java使用java.math.BigDecimal专门处理
    小数精度。
    2、如果是金融方面的金额计算,要非常的精确,用BigDecimal来修饰,但非要用String来够造BigDecimal不可,因为其他double,float构造的依旧不精确

    但是这样不停的转换会很麻烦,可以写个通用方法:
    import java.math.BigDecimal;
    
    /**
     * 由于Java的简单类型不能够精确的对浮点数进行运算,这个工具类提供精 确的浮点数运算,包括加减乘除和四舍五入。
     */
    public class Test {
    	// 默认除法运算精度,因为当除不尽时会报错
    	private static final int DEF_DIV_SCALE = 10;
    
    	/**
    	 * 提供精确的加法运算。
    	 * 
    	 * @param v1
    	 *            被加数
    	 * @param v2
    	 *            加数
    	 * @return 两个参数的和
    	 */
    	public static double add(double v1, double v2) {
    		BigDecimal b1 = new BigDecimal(Double.toString(v1));
    		BigDecimal b2 = new BigDecimal(Double.toString(v2));
    		return b1.add(b2).doubleValue();
    	}
    
    	/**
    	 * 提供精确的减法运算。
    	 * 
    	 * @param v1
    	 *            被减数
    	 * @param v2
    	 *            减数
    	 * @return 两个参数的差
    	 */
    	public static double sub(double v1, double v2) {
    		BigDecimal b1 = new BigDecimal(Double.toString(v1));
    		BigDecimal b2 = new BigDecimal(Double.toString(v2));
    		return b1.subtract(b2).doubleValue();
    	}
    
    	/**
    	 * 提供精确的乘法运算。
    	 * 
    	 * @param v1
    	 *            被乘数
    	 * @param v2
    	 *            乘数
    	 * @return 两个参数的积
    	 */
    	public static double mul(double v1, double v2) {
    		BigDecimal b1 = new BigDecimal(Double.toString(v1));
    		BigDecimal b2 = new BigDecimal(Double.toString(v2));
    		return b1.multiply(b2).doubleValue();
    	}
    
    	/**
    	 * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入。
    	 * 
    	 * @param v1
    	 *            被除数
    	 * @param v2
    	 *            除数
    	 * @return 两个参数的商
    	 */
    	public static double div(double v1, double v2) {
    		return div(v1, v2, DEF_DIV_SCALE);
    	}
    
    	/**
    	 * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。
    	 * 
    	 * @param v1
    	 *            被除数
    	 * @param v2
    	 *            除数
    	 * @param scale
    	 *            表示表示需要精确到小数点以后几位。
    	 * @return 两个参数的商
    	 */
    	public static double div(double v1, double v2, int scale) {
    		if (scale < 0) {
    			throw new IllegalArgumentException("The scale must be a positive integer or zero");
    		}
    		BigDecimal b1 = new BigDecimal(Double.toString(v1));
    		BigDecimal b2 = new BigDecimal(Double.toString(v2));
    		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    	}
    
    	/**
    	 * 提供精确的小数位四舍五入处理。
    	 * 
    	 * @param v
    	 *            需要四舍五入的数字
    	 * @param scale
    	 *            小数点后保留几位
    	 * @return 四舍五入后的结果
    	 */
    	public static double round(double v, int scale) {
    		if (scale < 0) {
    			throw new IllegalArgumentException("The scale must be a positive integer or zero");
    		}
    		BigDecimal b = new BigDecimal(Double.toString(v));
    		BigDecimal one = new BigDecimal("1");
    		return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
    	}
    }
    

      

     
    版权声明:如需转载,请注明!PS:如是转载随便,请忽略
  • 相关阅读:
    fn project 试用之后的几个问题的解答
    fn project 扩展
    fn project 生产环境使用
    fn project 对象模型
    fn project AWS Lambda 格式 functions
    fn project 打包Function
    fn project Function files 说明
    fn project hot functions 说明
    fn project k8s 集成
    fn project 私有镜像发布
  • 原文地址:https://www.cnblogs.com/zwdx/p/7510136.html
Copyright © 2011-2022 走看看