• BigDecimal类型的详情


    一、简介

       1、概述

        BigDecimal由任意精度的整数非标度值和32位的整数标度(scale)组成。如果为零或正数,则标度是小数点后的位数。如果为负数,则将该数的非标度值乘以10的负scale次幂。因此,BigDecimal表示的数值是(unscaleValue ×10-scale).

      2、构造函数  (主要为了说明double类型的构造函数)

        BigDecimal的String和double的构造函数实例:

    public static void main(String[] args) {
        BigDecimal bd1=new BigDecimal(1.22);
        System.out.println("double value"+bd1);
        BigDecimal bd2=new BigDecimal("1.22");
        System.out.println("String value"+bd2);
    }
    
    输出结果:
    
      double value==>:1.2199999999999999733546474089962430298328399658203125
      String value==>:1.22

    说明:

       1、参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。

            2、另一方面,String 构造方法是完全可预知的:写入 newBigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用String构造方法

            3、当double必须用作BigDecimal的源时,请注意,此构造方法提供了一个准确转换;它不提供与以下操作相同的结果:先使用Double.toString(double)方法,然后使用BigDecimal(String)构造方法,将double转换为String。要获取该结果,请使用static valueOf(double)方法。

    二、BigDecimal的加减乘除(以double类型的参数为示例)

      1、加法

        /**
         * 提供精确加法计算的add方法
         * @param value1 被加数
         * @param value2 加数
         * @return 两个参数的和
         */
        public static double add(double value1,double value2){
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.add(b2).doubleValue();
        }

      2、减法

        /**
         * 提供精确减法运算的sub方法
         * @param value1 被减数
         * @param value2 减数
         * @return 两个参数的差
         */
        public static double substract(double value1,double value2){
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.subtract(b2).doubleValue();
        }

      3、乘法

    /**
         * 提供精确乘法运算的mul方法
         * @param value1 被乘数
         * @param value2 乘数
         * @return 两个参数的积
         */
        public static double multiply(double value1,double value2){
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.multiply(b2).doubleValue();
        }

      4、除法

    /**
         * 提供精确的除法运算方法div
         * @param value1 被除数
         * @param value2 除数
         * @param scale 精确范围
         * @return 两个参数的商
         * @throws IllegalAccessException
         */
        public static double divide(double value1,double value2,int scale) throws IllegalAccessException{
        //如果精确范围小于0,抛出异常信息
        if(scale<0){ 
          throw new IllegalAccessException("精确度不能小于0");
        }
        BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
        BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
        return b1.divide(b2, scale,BigDecimal.ROUND_HALF_EVEN).doubleValue(); 
    }

    注意:对于除法获取精确度的方式有如下:

    static int

    ROUND_CEILING

               Rounding mode to round towards positive infinity.

    向正无穷方向舍入

    static int

    ROUND_DOWN

               Rounding mode to round towards zero.

    向零方向舍入

    static int

    ROUND_FLOOR

               Rounding mode to round towards negative infinity.

    向负无穷方向舍入

    static int

    ROUND_HALF_DOWN

               Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.

    向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5

    static int

    ROUND_HALF_EVEN

               Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor.

    向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP ,如果是偶数,使用ROUND_HALF_DOWN

    static int

    ROUND_HALF_UP

               Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.

    向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6

    static int

    ROUND_UNNECESSARY

               Rounding mode to assert that the requested operation has an exact result, hence no rounding is necessary.

    计算结果是精确的,不需要舍入模式

    static int

    ROUND_UP

               Rounding mode to round away from zero.

    向远离0的方向舍入

    b1.divide(b2, BigDecimal.ROUND_UP).doubleValue();

    三、其他

  • 相关阅读:
    常用的排序方法
    mongoose 操作
    formidable使用
    cors跨域(支持cookie跨域) node后台 express
    mongoose Schema写法
    vue生命周期钩子 (mounted 加载数据没有缓存用 activated 配合keep-alive组件)
    vue路由跳转 页面回到顶部
    RESTful风格的路由设计
    router-link 绑定事件不生效
    axios的Content-Type类型导致后台无法解析数据
  • 原文地址:https://www.cnblogs.com/renxiaoren/p/5280055.html
Copyright © 2020-2023  润新知