1. 程式人生 > >Java浮點數float,bigdecimal和double精確計算的精度誤差問題

Java浮點數float,bigdecimal和double精確計算的精度誤差問題

1.double小數轉bigdecimal後四捨五入計算有誤差
案例:

double g= 12.35;

BigDecimal bigG=new BigDecimal(g).setScale(1, BigDecimal.ROUND_HALF_UP);
//期望得到12.4

System.out.println(“test G:”+bigG.doubleValue());

test G:12.3

原因:

定義double g= 12.35; 而在計算機中二進位制表示可能這是樣:定義了一個g=12.34444444444444449,
new BigDecimal(g) g還是12.34444444444444449
new BigDecimal(g).setScale(1, BigDecimal.ROUND_HALF_UP); 得到12.3

正確的定義方式是使用字串建構函式:
new BigDecimal("12.35").setScale(1, BigDecimal.ROUND_HALF_UP)

bigdecimal比等方法
如浮點型別一樣, BigDecimal 也有一些令人奇怪的行為。尤其在使用 equals() 方法來檢測數值之間是否相等時要小心。 equals() 方法認為,兩個表示同一個數但換算值不同(例如, 100.00 和 100.000 )的 BigDecimal 值是不相等的。然而, compareTo() 方法會認為這兩個數是相等的,所以在從數值上比較兩個 BigDecimal 值時,應該使用 compareTo() 而不是 equals() 。

另外還有一些情形,任意精度的小數運算仍不能表示精確結果。例如, 1 除以 9 會產生無限迴圈的小數 .111111… 。出於這個原因,在進行除法運算時, BigDecimal 可以讓您顯式地控制舍入。 movePointLeft() 方法支援 10 的冪次方的精確除法。

與零比較:
int r=big_decimal.compareTo(BigDecimal.Zero); //和0,Zero比較
if(r0) //等於
if(r
1) //大於
if(r==-1) //小於