使用Java处理除法运算的陷阱
除法運算誰不會啊,很多人不屑一顧,其實除法、求余運算有一些陷阱。一旦計算發生了問題,還很不好找。不好找的原因主要是問題的偶然性太強,如果你知道可能發生什么問題,你的代碼就可以寫得更安全。
數學除法規定,0不能做除數,因為會得到一個無窮大數據。
西面看看Java中如何處理這些特殊情況:
1、整數的除法:
0做除數拋運行時異常;兩整數商會做取整運算,Float或Double與一個整數做除法運算,則商位Float或者Double類型,例如:
System.out.println("------------Int相關除法----------");? System.out.println("12/10="+12/10);? System.out.println("12f/10="+12f/10);? System.out.println("12d/10="+12d/10);? System.out.println("12/10f="+12/10d);? System.out.println("12/10d="+12/10f); |
------------Int相關除法----------? 12/10=1? 12f/10=1.2? 12d/10=1.2? 12/10f=1.2? 12/10d=1.2 |
2、Double(或Float)除法運算:
0可以做除數,得到的是一個分正負的無窮大;當兩個數的絕對值均為0.0時候,商等于NaN。當0.0/x,x不等0.0時候,得到的一個帶符號位0.0:
package?lavasoft.zerotest;? /**? *?浮點型數據的除法運算測試? *? *?@author?leizhimin?2009-12-21?9:00:37? */? public?class?TestZero?{? public?static?void?main(String[]?args)?{? System.out.println("------------Double型----------");? Double?x1?=?div(2.3,?0.0);? Double?x2?=?div(2.3,?-0.0);? Double?x3?=?div(0.0,?0.0);? Double?x4?=?div(0.0,?-0.0);? Double?x5?=?div(0.0,?0.1);? Double?x6?=?div(0.0,?-0.1);? if?(x1.isInfinite())?System.out.println("x1無窮大!");? if?(x2.isInfinite())?System.out.println("x2無窮大!");? if?(x3.isNaN())?System.out.println("x3非數字!");? if?(x4.isNaN())?System.out.println("x4非數字!");? if?(x1?==?Double.POSITIVE_INFINITY)?System.out.println("x1?=?Double.POSITIVE_INFINITY");? if?(x2?==?Double.NEGATIVE_INFINITY)?System.out.println("x1?=?Double.NEGATIVE_INFINITY");? if?(x3?==?Double.NaN)?System.out.println("x3?=?Double.NaN");? if?(x4?==?Double.NaN)?System.out.println("x4?=?-Double.NaN");? System.out.println("------------Float型----------");? Float?y1?=?div(2.3f,?0.0f);? Float?y2?=?div(2.3f,?-0.0f);? Float?y3?=?div(0.0f,?0.0f);? Float?y4?=?div(0.0f,?-0.0f);? Float?y5?=?div(0.0f,?-0.1f);? System.out.println("------------比較測試----------");? Float?a?=?99999999999999999999999999999999999999f;? Float?b?=?0.000000000000000000000000000000000000000000001f;? Float?t?=?a?/?b;? System.out.println(t);? System.out.println(Float.MAX_VALUE);? if?(t?>=?Float.MAX_VALUE)?{? System.out.println("a/b的商已經超過了Float的最大值了!");? }? }? public?static?Double?div(double?a,?double?b)?{? double?x?=?a?/?b;? System.out.println(a?+?"/"?+?b?+?"?=?"?+?x);? return?x;? }? public?static?Float?div(float?a,?float?b)?{? float?x?=?a?/?b;? System.out.println(a?+?"/"?+?b?+?"?=?"?+?x);? return?x;? }? } |
運算輸出:
------------Double型----------? 2.3/0.0?=?Infinity? 2.3/-0.0?=?-Infinity? 0.0/0.0?=?NaN? 0.0/-0.0?=?NaN? 0.0/0.1?=?0.0? 0.0/-0.1?=?-0.0? x1無窮大!? x2無窮大!? x3非數字!? x4非數字!? x1?=?Double.POSITIVE_INFINITY? x1?=?Double.NEGATIVE_INFINITY? ------------Float型----------? 2.3/0.0?=?Infinity? 2.3/-0.0?=?-Infinity? 0.0/0.0?=?NaN? 0.0/-0.0?=?NaN? 0.0/-0.1?=?-0.0? ------------比較測試----------? Infinity |
3.4028235E38
a/b的商已經超過了Float的最大值了!
Process finished with exit code 0
陷阱:
零在整數預算中不可以做除數,否則拋運行時異常。
零在浮點運算中可以做除數,返回值為無窮大。
NaN各不相同,可看做是Java設計上的一個缺陷。
浮點型(Float或Double)的除法運算可以接受任何數值,并且結果總是返回一個浮點型的數值。這個數值可能是不合法的,需要進行判斷和驗證。
3、求余:和除法差不多。
System.out.println(23%4);? System.out.println(23%-4);? System.out.println(-23%4);? System.out.println(23f%4);? System.out.println(23d%4);? System.out.println(23%4f);? System.out.println(23%4d);? System.out.println(23f%0);? System.out.println(23%0.0);? System.out.println(0.0%0.0); |
運行結果:
?? 3? 3? -3? 3.0? 3.0? 3.0? 3.0? NaN? NaN? NaN |
陷阱:
符號位由被除數決定。
對于Double、Float,API都提供了幾個有用的判斷方法,要注意運用其寫出安全的代碼:
boolean?isInfinite() |
如果該 Double 值的大小是無窮大,則返回 true;否則返回 false。
static?boolean?isInfinite(double?v) |
如果指定數字的大小是無窮大,則返回 true;否則,返回 false。
boolean?isNaN() |
如果此 Double 值是非數字(NaN)值,則返回 true;否則,返回 false。
static?boolean?isNaN(double?v) |
如果指定的數字是一個非數字 (NaN) 值,則返回 true;否則,返回 false。
Double、Float類中都提供了一些常量,也可用于判斷,當然這些常量也很有意思,看看源碼就知道了。
public?static?final?double?POSITIVE_INFINITY?=?1.0?/?0.0;? public?static?final?double?NEGATIVE_INFINITY?=?-1.0?/?0.0;? public?static?final?double?NaN?=?0.0d?/?0.0; |
總結
以上是生活随笔為你收集整理的使用Java处理除法运算的陷阱的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java多线程编程的常见陷阱
- 下一篇: java陷进