zoukankan      html  css  js  c++  java
  • BigDecimal

    java的float只能用来进行科学计算或工程计算,在大多数的商业计算中,一般采用java.math.BigDecimal类来进行精确计算。

    在使用BigDecimal类来进行计算的时候,主要分为以下步骤:

                 1、用float或者double变量构建BigDecimal对象。

                 2、通过调用BigDecimal的加,减,乘,除等相应的方法进行算术运算。

                 3、把BigDecimal对象转换成float,double,int等类型。

    Bigdecimal是无法直接用+-*/这些符号进行计算的,它有自己的运算方法,如下;
     
    public BigDecimal add(BigDecimal value);           //加法
    public BigDecimal subtract(BigDecimal value);      //减法 
    public BigDecimal multiply(BigDecimal value);      //乘法
    public BigDecimal divide(BigDecimal value);        //除法
    
    
    可以使用BigDecimal的构造方法或者静态方法的valueOf()方法把基本类型的变量构建成BigDecimal对象。
    BigDecimal一共有4个构造方法
    BigDecimal(int) 创建一个具有参数所指定整数值的对象。
    BigDecimal(double) 创建一个具有参数所指定双精度值的对象。
    BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
    BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象
    BigDecimal b2 = BigDecimal.valueOf(0.48);
    
    toString()             将BigDecimal对象的数值转换成字符串。
    doubleValue()          将BigDecimal对象中的值以双精度数返回。
    floatValue()           将BigDecimal对象中的值以单精度数返回。
    longValue()            将BigDecimal对象中的值以长整数返回。
    intValue()             将BigDecimal对象中的值以整数返回。
     
     进行相应的计算后,我们可能需要将BigDecimal对象转换成相应的基本数据类型的变量,可以使用floatValue(),doubleValue()等方法。
     
    可以在运算前后对其进行精度的设置:如下文:
    BigDecimal.setScale()方法用于格式化小数点
    setScale(1)表示保留一位小数,默认用四舍五入方式 
    setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3 
    setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4 
    setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4        适用元角分模式
    setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍
     
     
    注释:
    1:scale指的是你小数点后的位数。比如123.456则score就是3.
    score()就是BigDecimal类中的方法啊。
    比如:BigDecimal b = new BigDecimal("123.456");
    b.scale(),返回的就是3.
     
    2:roundingMode是小数的保留模式。它们都是BigDecimal中的常量字段,有很多种。
    比如:BigDecimal.ROUND_HALF_UP表示的就是4舍5入。

    3:pubilc BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
    的意思是说:我用一个BigDecimal对象除以divisor后的结果,并且要求这个结果保留有scale个小数位,roundingMode表示的就是保留模式是什么,是四舍五入啊还是其它的,你可以自己选!
     

    4:对于一般add、subtract、multiply方法的小数位格式化如下:

    BigDecimal mData = new BigDecimal("9.655").setScale(2, BigDecimal.ROUND_HALF_UP);
            System.out.println("mData=" + mData);
     
    ----结果:----- mData=9.66
     
    ========================================================================================
     
    精度设置,为什么会设置精度,给大家看个效果
     
    BigDecimal abig=new BigDecimal(10.0);  
    
    BigDecimal bbig=new BigDecimal(9.1);  
    
    BigDecimal cbig=new BigDecimal(8.9);  
    
    System.out.println(abig.subtract(bbig));  
    
    System.out.println(abig.subtract(cbig));  
    
    结果如下:
    
    0.9000000000000003552713678800500929355621337890625  
    
    1.0999999999999996447286321199499070644378662109375  
     
    并不是我们希望看到的0.9和1.1,原因就是转成二进制的时候会有精度问题,导致这样的结果。所以我们可以在运算的时候加精度,也可以在实例化BigDecimal的时候用字符串。
     
    设置精度的方法:
    
    System.out.println(abig.subtract(bbig).setScale(2, BigDecimal.ROUND_HALF_UP));  
    
    System.out.println(abig.subtract(cbig).setScale(2, BigDecimal.ROUND_HALF_UP));  
    这样设置两位精度就可以啦
    0.90  
    
    1.10  
     
    取反

    因为Bigdecimal是无法直接用+-*/这些符号进行计算的,所以取反的时候也需要一个单独的方法来实现:

    System.out.println(abig.negate());  

    这样就会拿到它的相反数了:

    -10.0 

    ========================================================================================
     以下是一个工具类,该工具类提供加,减,乘,除运算。转自:http://www.cnblogs.com/chenssy/archive/2012/09/09/2677279.html
    public class Arith {
        /**
         * 提供精确加法计算的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();
        }
        
        /**
         * 提供精确减法运算的sub方法
         * @param value1 被减数
         * @param value2 减数
         * @return 两个参数的差
         */
        public static double sub(double value1,double value2){
            BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
            BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
            return b1.subtract(b2).doubleValue();
        }
        
        /**
         * 提供精确乘法运算的mul方法
         * @param value1 被乘数
         * @param value2 乘数
         * @return 两个参数的积
         */
        public static double mul(double value1,double value2){
            BigDecimal b1 = new BigDecimal(Double.valueOf(value1));
            BigDecimal b2 = new BigDecimal(Double.valueOf(value2));
            return b1.multiply(b2).doubleValue();
        }
        
        /**
         * 提供精确的除法运算方法div
         * @param value1 被除数
         * @param value2 除数
         * @param scale 精确范围
         * @return 两个参数的商
         * @throws IllegalAccessException
         */
        public static double div(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).doubleValue();    
        }
    }

    格式化及例子
    由于NumberFormat类的format()方法可以使用BigDecimal对象作为其参数,可以利用BigDecimal对超出16位有效数字的货币值,百分值,以及一般数值进行格式化控制。

    以利用BigDecimal对货币和百分比格式化为例。首先,创建BigDecimal对象,进行BigDecimal的算术运算后,分别建立对货币和百分比格式化的引用,最后利用BigDecimal对象作为format()方法的参数,输出其格式化的货币值和百分比。

    public static void main(String[] args) {  
    
        NumberFormat currency = NumberFormat.getCurrencyInstance(); //建立货币格式化引用   
    
        NumberFormat percent = NumberFormat.getPercentInstance();  //建立百分比格式化引用   
    
        percent.setMaximumFractionDigits(3); //百分比小数点最多3位   
    
        BigDecimal loanAmount = new BigDecimal("15000.48"); //贷款金额  
    
        BigDecimal interestRate = new BigDecimal("0.008"); //利率     
    
        BigDecimal interest = loanAmount.multiply(interestRate); //相乘  
    
        System.out.println("贷款金额:	" + currency.format(loanAmount));   
    
        System.out.println("利率:	" + percent.format(interestRate));   
    
        System.out.println("利息:	" + currency.format(interest));   
    }
    
    
    运行结果如下:
    
    贷款金额:    ¥15,000.48  
    
    利率:    0.8%  
    
    利息:    ¥120.00  


    BigDecimal比较
    BigDecimal是通过使用compareTo(BigDecimal)来比较的,具体比较情况如下:

    public static void main(String[] args) {  
    
        BigDecimal a = new BigDecimal("1");  
    
        BigDecimal b = new BigDecimal("2");  
    
        BigDecimal c = new BigDecimal("1");  
    
        int result1 = a.compareTo(b);  
    
        int result2 = a.compareTo(c);  
    
        int result3 = b.compareTo(a);  
    
        System.out.println(result1);  
    
        System.out.println(result2);  
    
        System.out.println(result3);  
    
    }  
    
    打印结果是:-101,即左边比右边数大,返回1,相等返回0,比右边小返回-1
     
    注意不能使用equals方法来比较大小。

    使用BigDecimal的坏处是性能比double和float差,在处理庞大,复杂的运算时尤为明显,因根据实际需求决定使用哪种类型。

     

    Creating a NumberFormat

    Creating a NumberFormat for a specific Locale is done like this:

    Locale locale = new Locale("da", "DK");

    NumberFormat numberFormat = NumberFormat.getInstance(locale);

    和Locale  一起用会格式化一些国家的金额。

    详细API :http://tutorials.jenkov.com/java-internationalization/numberformat.html

     
  • 相关阅读:
    Brute Force
    2014 Asia AnShan Regional Contest --- HDU 5073 Galaxy
    dp --- 2014 Asia AnShan Regional Contest --- HDU 5074 Hatsune Miku
    2014 Asia AnShan Regional Contest --- HDU 5078 Osu!
    搜索 + 剪枝 --- POJ 1101 : Sticks
    Brute Force & STL --- UVA 146 ID Codes
    Brute Force --- UVA 10167: Birthday Cake
    UVA题目分类
    对全概率公式和贝叶斯公式的理解
    APPLE ID随意转区到US或者HK.不需要信用卡
  • 原文地址:https://www.cnblogs.com/xh_Blog/p/6485764.html
Copyright © 2011-2022 走看看