在上一篇文章中,咱們系統學習了 Java 裏面的包裝類,那麼這篇文章,咱們就來學習一下Java提供好的類——數學相關的類。java
在最先期學習 Java 基礎語法結構的時候,其實咱們學習並瞭解了加減乘除這些算數運算符,有了這些運算符,咱們就能夠作一些簡單的運算了,可是當咱們須要作一些比較複雜的運算的時候,其實用這些運算符是很難去處理的(好比獲取隨機數等等)。其實數學類對於咱們並不陌生,在學習 Java 基礎的時候,你必定用過 Math 類的,這個其實就是咱們最先期接觸的一個數學類了,其實與數學相關的類還有 BigInteger 類、BigDecimal 類等等,下面這個表格將這三個類作了一個小的梳理總結:api
數學類 | 所屬包 | 繼承關係 |
---|---|---|
Math類 | java.lang包,不須要導包 | 默認繼承Object基類 |
BigInteger類 | java.math包,須要導包 | 繼承自Number類,實現了Serializable, Comparable接口 |
BigDecimal類 | java.math包,須要導包 | 繼承自Number類,實現了Serializable, Comparable接口 |
下面咱們就對這三種類作一個詳細的學習。oracle
其實看源碼咱們看到,Math 這個類是 final 修飾的,意思就是不能讓子類去繼承的,只能使用這個類。dom
public final class Math {}
下面,咱們來詳細瞭解一下Math類ide
經過看源碼,咱們能夠得知 Math 這個類的構造方法是私有的,也就是咱們是不能建立對象的,爲何會這樣設計呢,實際上是由於 Math 類裏面的屬性和方法都是靜態的( static 修飾)。工具
/** * Don't let anyone instantiate this class. */ private Math() {}
int abs1 = Math.abs(-1); long abs2 = Math.abs(-3l); float abs3 = Math.abs(-1.2f); double abs4 = Math.abs(-3.923); System.out.println(abs1); System.out.println(abs2); System.out.println(abs3); System.out.println(abs4);
System.out.println(Math.ceil(-1.3));//-1.0 System.out.println(Math.ceil(1.9));//2.0 System.out.println(Math.ceil(-7.9));//-7.0 System.out.println(Math.ceil(123));//123.0
System.out.println(Math.floor(-1.3));//-2.0 System.out.println(Math.floor(1.9));//1.0 System.out.println(Math.floor(1.3));//1.0 System.out.println(Math.floor(-7.9));//-8.0 System.out.println(Math.floor(123));//123.0
System.out.println(Math.round(-1.3));//-1 System.out.println(Math.round(1.9));//2 System.out.println(Math.round(1.3));//1 System.out.println(Math.round(-7.9));//-8 System.out.println(Math.round(123));//123
System.out.println(Math.max(1, 3));//3 System.out.println(Math.max(-4, -5));//-4 System.out.println(Math.max(1.8, 1.92));//1.92 System.out.println(Math.max(-4f, -4f));//-4.0
System.out.println(Math.min(1, 3));//1 System.out.println(Math.min(-4, -5));//-5 System.out.println(Math.min(1.8, 1.92));//1.8 System.out.println(Math.min(-4f, -4f));//-4.0
System.out.println(Math.pow(3, 3));//27.0 System.out.println(Math.pow(3.2, 5));//335.5443200000001
System.out.println(Math.random());//0.4128879706448445 System.out.println(Math.random());//0.9024029619163387 System.out.println(Math.random());//0.4265563513755902
咱們都知道,在基本數據類型裏面,long型的取值範圍是最大的,也就是8個字節,取值範圍是-2的63次方到正的2的63次方減去1,固然,這個取值範圍很大很大,在平時的開發中,咱們其中只用到int類型的都基本夠了,可是當咱們存儲的數據的長度超過了 long 型的長度時,咱們該怎麼存儲呢?這時候,BigInteger 類就能夠解決咱們的問題。學習
BigInteger 顧名思義,其實就是叫大整數,也就是說只能存儲整型的數,咱們經過構造方法和經常使用方法來了解BigInteger 類。this
BigInteger 類有8個構造方法,其中有2個私有構造方法。8個構造方法分別是:設計
private BigInteger(int[] val){}
private BigInteger(int signum, int[] magnitude){}
public BigInteger(byte[] val){}
public BigInteger(String val){}
public BigInteger(String val, int radix) {}
public BigInteger(int signum, byte[] magnitude){}
public BigInteger(int numBits, Random rnd){}
public BigInteger(int bitLength, int certainty, Random rnd){}
當咱們想用這個類作四則運算的時候,是否是也能夠直接加減乘除呢,好比下面這張圖:3d
經過上面這張圖,BigInteger類直接作四則運算顯然是不能夠的,由於上面兩個數是引用類型,而運算符只能對基本數據類型作運算。那麼咱們怎麼作相應的四則運算呢?其實BigInteger類裏面其實已經幫咱們實現對應的方法,咱們直接用實例化的的對象調用它就好了。好比下方的代碼進行加減乘除:
private static void test6() { BigInteger num1 = new BigInteger("1111"); BigInteger num2 = new BigInteger("2222"); //加法 BigInteger add = num1.add(num2); //減法 BigInteger subtract = num2.subtract(num1); //乘法 final BigInteger multiply = num1.multiply(num2); //除法(取整) BigInteger divide = num2.divide(num1); //除法(取餘) BigInteger mod = num2.mod(num1); System.out.println(add);//3333 System.out.println(subtract);//1111 System.out.println(multiply);//2468642 System.out.println(divide);//2 System.out.println(mod);//0 }
與 BigInteger 類對應的是 BigDecimal 類,BigInteger 是處理整數的,而 BigDecimal 是處理小數的,Decimal 英文單詞就是小數的意思,因此 BigDecimal 顧名思義就是大小數,處理大的小數的。若是一個小數超過了 double類型的取值範圍,就須要用到 BigDecimal。
BigDecimal 類的構造方法有不少,最經常使用的是如下四個:
public BigDecimal(double val) {
public BigDecimal(int val) {}
public BigDecimal(String val) {}
public BigDecimal(long val) {}
和 BigInteger 類同樣,BigDecimal 也是不能夠直接進行加減乘除的,加減乘除的方式和 BigInteger 處理方式同樣,好比下面的代碼對BigDecimal 進行四則運算:
private static void test7() { BigDecimal num1 = new BigDecimal("1.23"); BigDecimal num2 = new BigDecimal("2.46"); //加法 BigDecimal add = num1.add(num2); //減法 BigDecimal subtract = num2.subtract(num1); //乘法 final BigDecimal multiply = num1.multiply(num2); //除法(取整) BigDecimal divide = num2.divide(num1); System.out.println(add);//3.69 System.out.println(subtract);//1.23 System.out.println(multiply);//3.0258 System.out.println(divide);//2 }
因爲小數和整數不同,小數常常涉及到精度的問題,因此 BigDecimal 裏面也提供了方法來設置小數的精度,設置精度的方法有三個重載的方法:
public BigDecimal setScale(int newScale)
public BigDecimal setScale(int newScale, int roundingMode)
public BigDecimal setScale(int newScale, RoundingMode roundingMode)
這三個方法的第一個參數是設置保留小數點以後的位數,第二個參數是設置的模式(好比向上取整仍是向下取整等等),設置四捨五入的模式有8種:
public final static int ROUND_UP = 0; public final static int ROUND_DOWN = 1; public final static int ROUND_CEILING = 2; public final static int ROUND_FLOOR = 3; public final static int ROUND_HALF_UP = 4; public final static int ROUND_HALF_DOWN = 5; public final static int ROUND_HALF_EVEN = 6; public final static int ROUND_UNNECESSARY = 7;
下面咱們就來對這其中4種模式的用法作一個詳細的分析
UP的意思就是向上的意思,能夠理解爲加的意思。好比我保留了三位小數,那麼我無論你後面的小數值如何(除了0),我都給你加一,就至關於四捨五入的五入。好比下面這個代碼,我保留3爲小數,模式設置爲ROUND_UP模式,那麼若是最後一位是0,那麼結果就是9.461,不然就是9.462
BigDecimal bigDecimal = new BigDecimal("9.4610"); BigDecimal result = bigDecimal.setScale(3, BigDecimal.ROUND_UP);
是一個舍位取值的概念,好比我保留了三位小數,那麼我無論你後面的小數值如何,也不會四捨五入,就硬生生的的截斷,至關於什麼呢,就是我從小數點後面開始取三位,三位後面的都不要了。好比下面這個代碼,我保留3爲小數,模式設置爲ROUND_DOWN模式,那麼最後一位不論是什麼(從0到9),最後的結果都是9.461
BigDecimal bigDecimal = new BigDecimal("9.4611"); BigDecimal result = bigDecimal.setScale(3, BigDecimal.ROUND_DOWN);
這個模式就是給定的數若是爲正數,行爲和ROUND_UP同樣,若是爲負數,行爲和ROUND_DOWN同樣 。
這個模式就是給定的數若是爲正數,行爲和ROUND_DOWN同樣,若是爲負數,行爲和ROUND_UP同樣
以上就是我對數學相關類的總結以及我的的理解,若是有任何不清楚的,能夠去看官方文檔(API官方文檔地址:https://docs.oracle.com/javase/8/docs/api/),其實,不少人都很排斥看源碼和閱讀官網文檔,緣由就是源碼和閱讀官網文檔都是全英文的,解讀起來很費時間;其實這是一種很差的學習方式,源碼和閱讀官網文檔是最官方權威的第一手資料,也是最正確的,若是咱們去網上看其餘的相關解讀,這也只能是他人的解讀,而其餘人的解讀就表明了他對源碼和閱讀官網文檔的我的理解,而這個理解是可能會有出入的,也就是可能會誤導咱們,因此咱們必定要養成習慣去閱讀源碼和閱讀官網文檔,可能剛開始的確很慢,可是慢慢的就你的閱讀速度和效率就會提升的。
公衆號:良許Linux