(轉貼)BigInteger 和 BigDecimal

          高精度數字
          Java 提供了兩個類專門用于進行高精度運算BigInteger 和 BigDecimal ,盡管它們可大致劃分到與封裝器相同的類別里,但兩者都沒有對應的主類型;這兩個類都有自己的一系列方法,類似于我們針對主類型執行的操作,也就是說能用 int 或float 做的事情,用BigInteger和BigDecimal 一樣可以做,只是必須換用方法調用,而不是使用運算符。此外由于牽涉更多,所以運算速度會慢一點總之我們犧牲了速度,但換來了精度。

          高精度浮點數BigDecimal

          一些非整數值(如幾美元和幾美分這樣的小數)需要很精確。浮點數不是精確值,所以使用它們會導致舍入誤差。因此,使用浮點數來試圖表示象貨幣量這樣的精確數量不是一個好的想法。使用浮點數來進行美元和美分計算會得到災難性的后果。浮點數最好用來表示象測量值這類數值,這類值從一開始就不怎么精確。
              從 JDK 1.3 起,Java 開發人員就有了另一種數值表示法來表示非整數:BigDecimal。BigDecimal 是標準的類,在編譯器中不需要特殊支持,它可以表示任意精度的小數,并對它們進行計算。在內部,可以用任意精度任何范圍的值和一個換算因子來表示 BigDecimal,換算因子表示左移小數點多少位,從而得到所期望范圍內的值。因此,用 BigDecimal 表示的數的形式為 unscaledValue*10-scale。
          用于加、減、乘和除的方法給  BigDecimal 值提供了算術運算。由于 BigDecimal 對象是不可變的,這些方法中的每一個都會產生新的 BigDecimal 對象。因此,因為創建對象的開銷,BigDecimal 不適合于大量的數學計算,但設計它的目的是用來精確地表示小數。如果您正在尋找一種能精確表示如貨幣量這樣的數值,則 BigDecimal 可以很好地勝任該任務。
          如浮點類型一樣,BigDecimal 也有一些令人奇怪的行為。尤其在使用 equals() 方法來檢測數值之間是否相等時要小心。equals() 方法認為,兩個表示同一個數但換算值不同(例如,100.00 和  100.000)的 BigDecimal 值是不相等的。然而,compareTo() 方法會認為這兩個數是相等的,所以在從數值上比較兩個  BigDecimal 值時,應該使用 compareTo() 而不是 equals()。
          另外還有一些情形,任意精度的小數運算仍不能表示精確結果。例如,1 除以 9 會產生無限循環的小數 .111111...。出于這個原因,在進行除法運算時,BigDecimal 可以讓您顯式地控制舍入。movePointLeft() 方法支持 10 的冪次方的精確除法。
          對于 BigDecimal,有幾個可用的構造函數。其中一個構造函數以雙精度浮點數作為輸入,另一個以整數和換算因子作為輸入,還有一個以小數的 String 表示作為輸入。要小心使用  BigDecimal(double) 構造函數, 因為如果不了解它,會在計算過程中產生舍入誤差。請使用基于整數或 String 的構造函數。
          如果使用 BigDecimal(double) 構造函數不恰當,在傳遞給 JDBC setBigDecimal() 方法時,會造成似乎很奇怪的 JDBC 驅動程序中的異常。例如,考慮以下 JDBC 代碼,該代碼希望將數字 0.01 存儲到小數字段:
            PreparedStatement ps =connection.prepareStatement("INSERT INTO Foo SET name=?, value=?");
            ps.setString(1, "penny");
            ps.setBigDecimal(2, new BigDecimal(0.01));
            ps.executeUpdate();
               在執行這段似乎無害的代碼時會拋出一些令人迷惑不解的異常(這取決于具體的 JDBC 驅動程序),因為 0.01 的雙精度近似值會導致大的換算值,這可能會使 JDBC 驅動程序或數據庫感到迷惑。JDBC 驅動程序會產生異常,但可能不會說明代碼實際上錯在哪里,除非意識到二進制浮點數的局限性。相反,使用 BigDecimal("0.01") 或 BigDecimal(1, 2) 構造 BigDecimal 來避免這類問題, 因為這兩種方法都可以精確地表示小數。
           

          code :

          import java.math.BigDecimal;
          /** * *
          * <p>Title: 開源,開放</p>
          * * <p>Description: opeansource</p>
          * * <p>Copyright: Copyright (c) 2004</p>
          * * <p>Company: ?海棠</p>
          * * @author HaiTang Ming
          * * @version 1.0 */
          public class BigDecimalUtil { 
          //默認除法運算精度,及即保留小數點多少位 
          private static final int DEF_DIV_SCALE = 2; 
          //這個類不能實例化 
          private BigDecimalUtil (){   } 
          /**   
            * * 提供精確的加法運算。   
            * * @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(); 

          /**   
            * * 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到   
            * * 小數點以后多少位,以后的數字四舍五入。   
            * * @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(); 
          }   
          public static void main(String[] args){   
            System.out.println(add(234.44,534.90));
           
            double a = 123.345678;   
            double d = round(a,2);   
            System.out.println("round("+a+",2)--->"+d); 
          }
          }

          高精度整數BigInteger

          BigInteger支持任意精度的整數,也就是說我們可精確表示任意大小的整數值;同時在運算過程中不會丟失任何信息;
          在BigInteger類中有所有的基本算術運算方法,如加、減、乘、除,以及可能會用到的位運算如或、異或、非、左移、右移等。下面是一些方法的例子:當然,如果要有更多的使用方法,可以查閱java api 。

          code :public class BigIntegerTest { 
          public BigIntegerTest() {   } 
          /**   
            * * 測試BigInteger
            * */ 
          public static void testBigInteger() {   
            BigInteger bi = new BigInteger("888");   
            //multiply :乘法   
            BigInteger result = bi.multiply(new BigInteger("2"));   
            System.out.println(result);   
            //divide : 除法   
            result = bi.divide(new BigInteger("2"));   
            System.out.println(result);   
            //add : 加法   
            result = bi.add(new BigInteger("232"));   
            System.out.println(result);   
            //subtract :減法   
            result = bi.subtract(new BigInteger("23122"));   
            System.out.println(result);   
            result = bi.shiftRight(2);   
            System.out.println(result); 
          }   
          public static void main(String[] args) {   
            testBigInteger(); 
          }
          }
          原貼地址http://dev.firnow.com/course/3_program/java/javaxl/2008914 /142796_2.html

          posted on 2010-12-10 14:16 AK47 閱讀(1031) 評論(0)  編輯  收藏 所屬分類: java相關

          <2010年12月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導航

          統計

          常用鏈接

          留言簿

          隨筆分類

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 霍邱县| 屯门区| 西昌市| 罗城| 大足县| 许昌市| 平果县| 唐河县| 达州市| 中超| 洪江市| 广平县| 凉城县| 玉环县| 繁峙县| 丹东市| 桐庐县| 介休市| 杭锦后旗| 上栗县| 河曲县| 勐海县| 古浪县| 荥阳市| 太原市| 云南省| 绍兴市| 山丹县| 鹤壁市| 镇安县| 临汾市| 安阳市| 同德县| 浮山县| 青岛市| 麻城市| 马尔康县| 榆中县| 洛浦县| 平利县| 渭源县|