首页> 开发语言> Java 使用BigDecimal类处理高精度计算

[文章]Java 使用BigDecimal类处理高精度计算

收藏
0 576 0

  【摘要】 

首先明确的是:Java中的浮点数类型的floatdouble是不能够用来进行资金的运算。floatdouble只能用来做科学计算或者是工程计算,在商业计算中我们要用java.math.BigDecimal

双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的数进行运算和处理。一般情况下,对于那些不需要准确计算精度的数字,我们可以直接使用FloatDouble处理,但是Double.valueOf(String) Float.valueOf(String)会丢失精度。所以开发中,如果我们需要精确计算的结果,则必须使用BigDecimal类来操作。

【正文】

下面就来介绍一下BigDecimal类。

(一)BigDecimal类的常用的几个构造方法

 

BigDecimal(int):将int表示形式转换为BigDecimal对象

BigDecimal(String) :将字符串表示形式转换为BigDecimal对象

BigDecimal(double):将double表示形式转换为BigDecimal对象

 

 

(二)BigDecimal类的常用方法

 

add(BigDecimal)BigDecimal对象中的值相加,返回BigDecimal对象

subtract(BigDecimal)BigDecimal对象中的值相减,返回BigDecimal对象

multiply(BigDecimal)BigDecimal对象中的值相乘,返回BigDecimal对象

divide(BigDecimal)BigDecimal对象中的值相除,返回BigDecimal对象

toString():将BigDecimal对象中的值转换成字符串

doubleValue():将BigDecimal对象中的值转换成双精度数

floatValue():将BigDecimal对象中的值转换成单精度数

longValue():将BigDecimal对象中的值转换成长整数

intValue():将BigDecimal对象中的值转换成整数

 

下面分享一个用于高精确处理常用的数学运算类

package com.per.test;

 

import java.math.BigDecimal;

/**

 * 用于高精确处理常用的数学运算

 * Created by lijuan on 2016/8/27.

 */

public class ArithmeticUtils {

    //默认除法运算精度

    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 BigDecimal add(String v1, String v2) {

        BigDecimal b1 = new BigDecimal(v1);

        BigDecimal b2 = new BigDecimal(v2);

        return b1.add(b2);

    }

 

    /**

     * 提供精确的加法运算

     *

     * @param v1    被加数

     * @param v2    加数

     * @param scale 保留scale 位小数

     * @return 两个参数的和

     */

    public static String add(String v1, String v2, int scale) {

        if (scale < 0) {

            throw new IllegalArgumentException(

                    "The scale must be a positive integer or zero");

        }

        BigDecimal b1 = new BigDecimal(v1);

        BigDecimal b2 = new BigDecimal(v2);

        return b1.add(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();

    }

 

    /**

     * 提供精确的减法运算

     *

     * @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 BigDecimal sub(String v1, String v2) {

        BigDecimal b1 = new BigDecimal(v1);

        BigDecimal b2 = new BigDecimal(v2);

        return b1.subtract(b2);

    }

 

    /**

     * 提供精确的减法运算

     *

     * @param v1    被减数

     * @param v2    减数

     * @param scale 保留scale 位小数

     * @return 两个参数的差

     */

    public static String sub(String v1, String v2, int scale) {

        if (scale < 0) {

            throw new IllegalArgumentException(

                    "The scale must be a positive integer or zero");

        }

        BigDecimal b1 = new BigDecimal(v1);

        BigDecimal b2 = new BigDecimal(v2);

        return b1.subtract(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();

    }

 

    /**

     * 提供精确的乘法运算

     *

     * @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();

    }

 

    /**

     * 提供精确的乘法运算

     *

     * @param v1 被乘数

     * @param v2 乘数

     * @return 两个参数的积

     */

    public static BigDecimal mul(String v1, String v2) {

        BigDecimal b1 = new BigDecimal(v1);

        BigDecimal b2 = new BigDecimal(v2);

        return b1.multiply(b2);

    }

 

 

    /**

     * 提供精确的乘法运算

     *

     * @param v1    被乘数

     * @param v2    乘数

     * @param scale 保留scale 位小数

     * @return 两个参数的积

     */

    public static double mul(double v1, double v2, int scale) {

        BigDecimal b1 = new BigDecimal(Double.toString(v1));

        BigDecimal b2 = new BigDecimal(Double.toString(v2));

        return round(b1.multiply(b2).doubleValue(), scale);

    }

 

    /**

     * 提供精确的乘法运算

     *

     * @param v1    被乘数

     * @param v2    乘数

     * @param scale 保留scale 位小数

     * @return 两个参数的积

     */

    public static String mul(String v1, String v2, int scale) {

        if (scale < 0) {

            throw new IllegalArgumentException(

                    "The scale must be a positive integer or zero");

        }

        BigDecimal b1 = new BigDecimal(v1);

        BigDecimal b2 = new BigDecimal(v2);

        return b1.multiply(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();

    }

 

    /**

     * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到

     * 小数点以后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();

    }

 

    /**

     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指

     * 定精度,以后的数字四舍五入

     *

     * @param v1    被除数

     * @param v2    除数

     * @param scale 表示需要精确到小数点以后几位

     * @return 两个参数的商

     */

    public static String div(String v1, String v2, int scale) {

        if (scale < 0) {

            throw new IllegalArgumentException("The scale must be a positive integer or zero");

        }

        BigDecimal b1 = new BigDecimal(v1);

        BigDecimal b2 = new BigDecimal(v1);

        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();

    }

 

    /**

     * 提供精确的小数位四舍五入处理

     *

     * @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));

        return b.setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue();

    }

 

    /**

     * 提供精确的小数位四舍五入处理

     *

     * @param v     需要四舍五入的数字

     * @param scale 小数点后保留几位

     * @return 四舍五入后的结果

     */

    public static String round(String v, int scale) {

        if (scale < 0) {

            throw new IllegalArgumentException(

                    "The scale must be a positive integer or zero");

        }

        BigDecimal b = new BigDecimal(v);

        return b.setScale(scale, BigDecimal.ROUND_HALF_UP).toString();

    }

 

 

    /**

     * 取余数

     *

     * @param v1    被除数

     * @param v2    除数

     * @param scale 小数点后保留几位

     * @return 余数

     */

    public static String remainder(String v1, String v2, int scale) {

        if (scale < 0) {

            throw new IllegalArgumentException(

                    "The scale must be a positive integer or zero");

        }

        BigDecimal b1 = new BigDecimal(v1);

        BigDecimal b2 = new BigDecimal(v2);

        return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();

    }

 

    /**

     * 取余数  BigDecimal

     *

     * @param v1    被除数

     * @param v2    除数

     * @param scale 小数点后保留几位

     * @return 余数

     */

    public static BigDecimal remainder(BigDecimal v1, BigDecimal v2, int scale) {

        if (scale < 0) {

            throw new IllegalArgumentException(

                    "The scale must be a positive integer or zero");

        }

        return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);

    }

 

    /**

     * 比较大小

     *

     * @param v1 被比较数

     * @param v2 比较数

     * @return 如果v1 大于v2 返回true 否则false

     */

    public static boolean compare(String v1, String v2) {

        BigDecimal b1 = new BigDecimal(v1);

        BigDecimal b2 = new BigDecimal(v2);

        int bj = b1.compareTo(b2);

        boolean res;

        if (bj > 0)

            res = true;

        else

            res = false;

        return res;

    }

}

开发语言
最近热帖
{{item.Title}} {{item.ViewCount}}
近期热议
{{item.Title}} {{item.PostCount}}