1. 程式人生 > 程式設計 >解決BigDecimal轉long丟失精度的問題

解決BigDecimal轉long丟失精度的問題

我就廢話不多說了,大家還是直接看程式碼吧~

  public static void main(String[] args) {
    BigDecimal asdBigDecimal = new BigDecimal(56.33347);
    long sad = asdBigDecimal.longValue();
    double asda = asdBigDecimal.doubleValue();
    System.out.println(sad);
    System.out.println(asda);
  }

執行結果:

56

56.33347

而且BigDecimal.longValue()還會自動四捨五入,不想捨去小數點的朋友要用doubleValue()

補充知識:BigDecimal與int、long之間的相互轉換及基本資料型別知識掌握

(Java提供了兩個用於高精度計算的類:BigInteger和BigDecimal。這兩個類包含的方法、提供的操作與對基本型別所能執行的操作相似,只不過是以方法呼叫方式取代運算子方式來實現。等於是用速度換取了精度。 BigInteger支援任意精度的整數,在運算中可以準確地表示任何大小的整數值,而不會丟失任何資訊。BigDecimal支援任何精度的定點數,可以用它進行精確的貨幣計算。

它們都擴充套件Number類且實現Comparable介面,可以使用new BigInteger(String)或new BigDecimal(String)來建立例項,使用add,substract,multiple,divide和remainder方法完成算數運算,使用compareTo方法比較兩個大數字。

一般來說,BigInteger用的不是很多,BigDecimal用的稍微多一點,就比如說JDBC中,如果一個欄位的資料庫型別是Number,那麼getObject().getClass()的結果是java.math.BigDecimal。  

BigInteger相比Integer的確可以用big來形容。它是用於科學計算,Integer只能容納一個int,所以最大值也就是2的31次訪減去1,十進位制為2147483647,如果需要計算更大的數,那麼31位顯然是不夠用了,BigInteger能夠容納的位數那可就大了,我簡單試了一下,上千位沒有任何問題。除了容量大之外,BigInteger還封裝了一些常見的操作,比如+-*/的基本操作,還有絕對值,相反數,最大公約數,是否是質數等等的運算。  

BigDecimal的實現利用到了BigInteger,所不同的是BigDecimal加入了小數位的概念,比如BigDecimal d = new BigDecimal(new BigInteger(ib),5);5表示的是5個小數位。BigDecimal可以用來做超大的浮點數的運算,比如+-*/的運算,其中除法運算是最複雜的,因為商的位數還有除不斷的情況下末位小數點的處理都是需要考慮的。)

我們在實際開發過程中,BigDecimal是經常用到的一個數據型別,它和int、long之間可以專案轉換。

int 轉換成 BigDecimal 資料型別

 //int 轉換成 bigDecimal型別
  public static void intToBigDecimal(){
    int b = 5;
    BigDecimal a = new BigDecimal(b);
    System.out.println(a +"的資料型別是"+a.getClass().getName());
  }

Long轉換成 BigDecimal 資料型別

 //Long 型別轉換成 bigDecimal
  public static void longToBigDecimal(){
    long b = 5;
    BigDecimal a = new BigDecimal(b);
    System.out.println(a +"的資料型別是"+a.getClass().getName());
  }

BigDecimal 轉換成 Long資料型別

 //bigDecimal 轉換成 Long型別
  public static void bigDecimalToLong(){
    BigDecimal b = new BigDecimal(12);
    Long c = b.longValue();
    System.out.println(c+"的資料型別是"+c.getClass().getName());
  }

BigDecimal 轉換成 int資料型別

  //bigDecimal 轉換成 int型別
    public static void bigDecimalToInt(){
      BigDecimal b = new BigDecimal(12);
      int c = b.intValue();
    }

附:基本資料型別及所佔位數及初始值

基本資料型別 所佔位數 初始值
byte 位元組型 1位元組(8bit) 0
short 短整型 2位元組(16bit) 0
int 整型 4位元組(32bit) 0
long 長整型 8位元組(64bit) 0L
float 單精度浮點型 4位元組(32bit) 0.0f
double 雙精度浮點型 8位元組(64bit) 0.0d
boolean java未明確指出的大小(可能1bit、1byte、4byte) false
char 字元型 2位元組(16bit) 空格

附:java的資料型別

解決BigDecimal轉long丟失精度的問題

附:轉換中的知識點

java中整數型別預設的int型別;小數型別預設的double;

*char 可以當做一中特殊的整數型別;
*int無法轉換為boolean;
*小數型別轉為整數型別,小數可能被捨棄,所有出現精度損失,所以需要強制轉換;
*boolean 型別不能轉換成任何其它資料型別;
byte b2 = 120;
//沒報錯的原因:
//編譯時候,進行檢查,看賦值大小是否超過變數的型別所容納的範圍
//如果超過,報錯:從int轉換到byte可能會有損失,如果沒超過,編譯通過
float f3 = 100L; 這種情況,整數部分,可以直接賦值給float整數部分
float f1 = 100.9; 這種情況,因為預設的是double,如果這樣轉換,有可能失去小數點,必須強制轉換
long l3 = 1000.9f; 小數轉為整數,小數可能丟失,需要強制轉換
double d2 = 10.9d;
int i2 = d2; //錯誤: 不相容的型別: 從double轉換到int可能會有損失
char c1 = 'a';
int i3 = c1; //自動轉換
int i4 = 100;
//char c2 = i4;// 錯誤: 不相容的型別: 從int轉換到char可能會有損失

附:四則運算

/*
1、如果兩個運算元中有一個是double型別,另一個就會轉換為double型別;
2、否則,如果有一個運算元是float,另一個就會轉化為float;
3、否則,如果有一個運算元是long,另一個就會轉換為long;
4、否則,兩個運算元都將轉換為int型別。 
*/ 

附:面試陷阱

byte b1 = 10;
byte b2 = 11;
//錯誤: 不相容的型別: 從int轉換到byte可能會有損失
//否則,兩個運算元都將轉換為int型別。
byte b3 = b1 + b2 //錯誤
byte b3 = (byte)(b1 + b2); //正確
short s1 = 1; 
s1 = s1 + 1; //錯誤: 不相容的型別: 從int轉換到short可能會有損失
 
short s2 = 1; 
s2 += 1; // 等同於short s2 = (short)(s2 + (short)1); //正確

附:從小到大順序

解決BigDecimal轉long丟失精度的問題

附:隱式轉換、顯式轉換

當將佔位數少的型別賦值給佔位數多的型別時,java自動使用隱式型別轉換(如int型轉為long型)

當把在級別高的變數的值賦給級別低變數時,必須使用顯式型別轉換運算(如double型轉為float型)

附:什麼是不可變物件

不可變物件指物件一旦被建立,狀態就不能再改變。任何修改都會建立一個新的物件,如String、Integer及其它包裝類。

以上這篇解決BigDecimal轉long丟失精度的問題就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。