java中如何使用BigDecimal使得Double類型保留兩位有效數字


一、場景:從數據表中讀出Decimal類型的數據直接塞給Double類型的對象時,並不會有什么異常。

如果要再此基礎上計算,就會發生異常。

比如:讀出數據為0.0092,將其乘以100,則變成了0.919999999999999...

二、原因:

java mysql 數據類型對照如下:

類型名稱 顯示長度 數據庫類型 JAVA類型 JDBC類型索引(int) 描述
           
VARCHAR L+N VARCHAR java.lang.String 12  
CHAR N CHAR java.lang.String 1  
BLOB L+N BLOB java.lang.byte[] -4  
TEXT 65535 VARCHAR java.lang.String -1  
           
INTEGER 4 INTEGER UNSIGNED java.lang.Long 4  
TINYINT 3 TINYINT UNSIGNED java.lang.Integer -6  
SMALLINT 5 SMALLINT UNSIGNED java.lang.Integer 5  
MEDIUMINT 8 MEDIUMINT UNSIGNED java.lang.Integer 4  
BIT 1 BIT java.lang.Boolean -7  
BIGINT 20 BIGINT UNSIGNED java.math.BigInteger -5  
FLOAT 4+8 FLOAT java.lang.Float 7  
DOUBLE 22 DOUBLE java.lang.Double 8  
DECIMAL 11 DECIMAL java.math.BigDecimal 3  
BOOLEAN 1 同TINYINT      
           
ID 11 PK (INTEGER UNSIGNED) java.lang.Long 4  
           
DATE 10 DATE java.sql.Date 91  
TIME 8 TIME java.sql.Time 92  
DATETIME 19 DATETIME java.sql.Timestamp 93  
TIMESTAMP 19 TIMESTAMP java.sql.Timestamp 93  
YEAR 4 YEAR java.sql.Date 91






 

三、解決方案:

1、將double類型重新變成BigDecimal類型,最后的結果還要獲取有效位數

double d = 111231.5585;   

BigDecimal b = new BigDecimal(f);  

double df = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); 

2、因為數據表里的類型是Decimal,所以講java對象中對應的成員變量的類型改成BigDecimal即可。

 

四、BigDecimal簡介

在mysql中,對於精度比較高的數據存儲,比如money,需要用decimal類型,而不會采用float或double類型,原因在於后者數據誤差較大。

decimal列的聲明語法是decimal(m,d)。

在mysql 5.1中,參數的取值范圍: 

1、M是數字的最大數(精度)。其范圍為1~65(在較舊的MySQL版本中,允許的范圍是1~254)。 

2、D是小數點右側數字的數目(標度)。其范圍是0~30,但不得超過M。 
說明:float占4個字節,double占8個字節,decimail(M,D)占M+2個字節。 
如DECIMAL(5, 2) 的最大值為9 9 9 9 . 9 9,因為有7 個字節可用。 
 
注: 
M 與D 對DECIMAL(M, D) 取值范圍的影響 
 

類型說明 取值范圍(MySQL < 3.23) 取值范圍(MySQL >= 3.23) 
DECIMAL(4, 1) -9.9 到 99.9 -999.9 到 9999.9 
DECIMAL(5, 1) -99.9 到 999.9 -9999.9 到 99999.9 
DECIMAL(6, 1) -999.9 到 9999.9 -99999.9 到 999999.9 
DECIMAL(6, 2) -99.99 到 999.99 -9999.99 到 99999.99 
DECIMAL(6, 3) -9.999 到 99.999 -999.999 到 9999.999
 

 
# 在mysql 3.23 及以后的版本中,decimal(m, d) 的取值范圍等於早期版本中的decimal(m + 2, d) 的取值范圍。 
 
另外一種數據類型:
LongBlob,這種數據類型可以直接把圖像文件存到數據表中! 
 
在研究mysql的decimal數據類型,現把數據實驗結果公布: 
數據庫版本:Server version: 5.0.45 Source distribution 
 
1、創建表結構 
 

create table ta (a float,b decimal(10,5));
 

2、插入數據 
 

insert into ta (a,b) values(1,12345.123423);
 

實際插入的b列數據為:12345.12342 
 

insert into ta (a,b) values(1,123456.1234);

實際插入的b列數據為:99999.99999

結論:decimal數據類型, 
1、當插入的整數部分的值超過了其表示范圍后就直接忽略了小數部分的值,並以最大值填充。 
2、當整數部分合法,小數部分多余的位數,直接截斷。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM