開篇,國際慣例模式 「先吹牛」,先給小白科普一下 BigDecimal。
Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變量double可以處理16位有效數,但在實際應用中,可能需要對更大或者更小的數進行運算和處理。一般情況下,對於那些不需要準確計算精度的數字,我們可以直接使用Float和Double處理,但是Double.valueOf(String) 和Float.valueOf(String)會丟失精度。所以開發中,如果我們需要精確計算的結果,則必須使用BigDecimal類來操作。
BigDecimal所創建的是對象,故我們不能使用傳統的+、-、*、/等算術運算符直接對其對象進行數學運算,而必須調用其相對應的方法。方法中的參數也必須是BigDecimal的對象。構造器是類的特殊方法,專門用來創建對象,特別是帶有參數的對象。
BigDecimal對象中的值相加,返回BigDecimal對象
BigDecimal對象中的值相減,返回BigDecimal對象。
BigDecimal對象中的值相乘,返回BigDecimal對象。
BigDecimal對象中的值相除,返回BigDecimal對象。
搭配 NumberFormat 類的 format() 方法可以直接將 BigDecimal 對象作為參數進行格式化處理,可以對超出16位有效數字的貨幣值、百分值、以及一般數值進行格式化控制。
這裡是本文重點要科普的點,雖然內容不多,但是較為重要!如果你做銀行、金融相關領域,則更應該掌握。
打開 BigDecimal 類,可以看到如下幾個常量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;所謂銀行家捨入法,其實質是一種四捨六入五取偶(又稱四捨六入五留雙)法。
System.out.println(new BigDecimal(1.15).setScale(1,BigDecimal.ROUND_HALF_EVEN).toString());如果你告訴我輸出的是 1.2,那你就又錯了,它輸出的結果是 1.1。哈哈哈……
我來告訴你為什麼,代碼中 new BigDecimal(1.15) 會丟失精度,請使用 new BigDecimal("1.15") 這樣的寫法!
所以,銀行家捨入法 BigDecimal.ROUND_HALF_EVEN 應當選本文的主角,請記住它。
最後,為什麼銀行家捨入是相對很合理的呢?這個問題留給你,數據模型會告訴你答案 —— 它確實相對很合理。