為什么浮點數運算的時候會有精度丟失的風險?
浮點數運算精度丟失代碼演示:
float a = 2.0f - 1.9f;
float b = 1.8f - 1.7f;
System.out.println(a);// 0.100000024
System.out.println(b);// 0.099999905
System.out.println(a == b);// false
為什么會出現這個問題呢?
????????這個和計算機保存浮點數的機制有很大關系。我們知道計算機是二進制的,而且計算機在表示一個數字時,寬度是有限的,無限循環的小數存儲在計算機時,只能被截斷,所以就會導致小數精度發生損失的情況。這也就是解釋了為什么浮點數沒有辦法用二進制精確表示。
????????就比如說十進制下的 0.2 就沒辦法精確轉換成二進制小數:
// 0.2 轉換為二進制數的過程為,不斷乘以 2,直到不存在小數為止,
// 在這個計算過程中,得到的整數部分從上到下排列就是二進制的結果。
0.2 * 2 = 0.4 -> 0
0.4 * 2 = 0.8 -> 0
0.8 * 2 = 1.6 -> 1
0.6 * 2 = 1.2 -> 1
0.2 * 2 = 0.4 -> 0(發生循環)
...
如何解決浮點數運算的精度丟失問題?
???BigDecimal
可以實現對浮點數的運算,不會造成精度丟失。通常情況下,大部分需要浮點數精確運算結果的業務場景(比如涉及到錢的場景)都是通過 BigDecimal
來做的。
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
BigDecimal c = new BigDecimal("0.8");BigDecimal x = a.subtract(b);
BigDecimal y = b.subtract(c);System.out.println(x); /* 0.1 */
System.out.println(y); /* 0.1 */
System.out.println(Objects.equals(x, y)); /* true */
超過 long 整型的數據應該如何表示?
????????基本數值類型都有一個表達范圍,如果超過這個范圍就會有數值溢出的風險。在 Java 中,64 位 long 整型是最大的整數類型。
long l = Long.MAX_VALUE;
System.out.println(l + 1); // -9223372036854775808
System.out.println(l + 1 == Long.MIN_VALUE); // true
???BigInteger
內部使用 int[]
數組來存儲任意大小的整形數據。相對于常規整數類型的運算來說,BigInteger
運算的效率會相對較低。
更多消息資訊,請訪問昂焱數據。昂焱數據