使用Java处理除法运算的陷阱
除法運(yùn)算誰(shuí)不會(huì)啊,很多人不屑一顧,其實(shí)除法、求余運(yùn)算有一些陷阱。一旦計(jì)算發(fā)生了問(wèn)題,還很不好找。不好找的原因主要是問(wèn)題的偶然性太強(qiáng),如果你知道可能發(fā)生什么問(wèn)題,你的代碼就可以寫得更安全。
數(shù)學(xué)除法規(guī)定,0不能做除數(shù),因?yàn)闀?huì)得到一個(gè)無(wú)窮大數(shù)據(jù)。
西面看看Java中如何處理這些特殊情況:
1、整數(shù)的除法:
0做除數(shù)拋運(yùn)行時(shí)異常;兩整數(shù)商會(huì)做取整運(yùn)算,Float或Double與一個(gè)整數(shù)做除法運(yùn)算,則商位Float或者Double類型,例如:
System.out.println("------------Int相關(guān)除法----------");? 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相關(guān)除法----------? 12/10=1? 12f/10=1.2? 12d/10=1.2? 12/10f=1.2? 12/10d=1.2 |
2、Double(或Float)除法運(yùn)算:
0可以做除數(shù),得到的是一個(gè)分正負(fù)的無(wú)窮大;當(dāng)兩個(gè)數(shù)的絕對(duì)值均為0.0時(shí)候,商等于NaN。當(dāng)0.0/x,x不等0.0時(shí)候,得到的一個(gè)帶符號(hào)位0.0:
package?lavasoft.zerotest;? /**? *?浮點(diǎn)型數(shù)據(jù)的除法運(yùn)算測(cè)試? *? *?@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無(wú)窮大!");? if?(x2.isInfinite())?System.out.println("x2無(wú)窮大!");? if?(x3.isNaN())?System.out.println("x3非數(shù)字!");? if?(x4.isNaN())?System.out.println("x4非數(shù)字!");? 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("------------比較測(cè)試----------");? 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的商已經(jīng)超過(guò)了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;? }? } |
運(yùn)算輸出:
------------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無(wú)窮大!? x2無(wú)窮大!? x3非數(shù)字!? x4非數(shù)字!? 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? ------------比較測(cè)試----------? Infinity |
3.4028235E38
a/b的商已經(jīng)超過(guò)了Float的最大值了!
Process finished with exit code 0
陷阱:
零在整數(shù)預(yù)算中不可以做除數(shù),否則拋運(yùn)行時(shí)異常。
零在浮點(diǎn)運(yùn)算中可以做除數(shù),返回值為無(wú)窮大。
NaN各不相同,可看做是Java設(shè)計(jì)上的一個(gè)缺陷。
浮點(diǎn)型(Float或Double)的除法運(yùn)算可以接受任何數(shù)值,并且結(jié)果總是返回一個(gè)浮點(diǎn)型的數(shù)值。這個(gè)數(shù)值可能是不合法的,需要進(jìn)行判斷和驗(yàn)證。
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); |
運(yùn)行結(jié)果:
?? 3? 3? -3? 3.0? 3.0? 3.0? 3.0? NaN? NaN? NaN |
陷阱:
符號(hào)位由被除數(shù)決定。
對(duì)于Double、Float,API都提供了幾個(gè)有用的判斷方法,要注意運(yùn)用其寫出安全的代碼:
boolean?isInfinite() |
如果該 Double 值的大小是無(wú)窮大,則返回 true;否則返回 false。
static?boolean?isInfinite(double?v) |
如果指定數(shù)字的大小是無(wú)窮大,則返回 true;否則,返回 false。
boolean?isNaN() |
如果此 Double 值是非數(shù)字(NaN)值,則返回 true;否則,返回 false。
static?boolean?isNaN(double?v) |
如果指定的數(shù)字是一個(gè)非數(shù)字 (NaN) 值,則返回 true;否則,返回 false。
Double、Float類中都提供了一些常量,也可用于判斷,當(dāng)然這些常量也很有意思,看看源碼就知道了。
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; |
總結(jié)
以上是生活随笔為你收集整理的使用Java处理除法运算的陷阱的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Java多线程编程的常见陷阱
- 下一篇: Java内存管理的9个小技巧