標籤:
這兩天,由於我的必修課機率論裡經常要用到排列組合的計算,感覺很麻煩,加上現代智能手機的計算機是沒有這方面功能的。
所以,就自己動手寫了個安卓的 排列組合 計算機,用了一天,發現有很大的問題,階乘達百億層級的數,程式將不再運行。
我這裡舉個例子,30的階乘,30!=1x2x3x4x5....x30,這個明顯是超出了整型 int 的範圍了。
心想,試試長整型吧,後來發現,8位元組的long 也是杯水車薪。
無奈求助百度,發現個好東西,BigDecimal 類。
查看了若干相關博文,發現全 TM 是複製粘貼文檔的,我是服了,沒有那一篇是有個人見解的,直接copy文檔
demo例子不夠清晰,看著真是蛋疼,從頭到尾,只說它是怎麼怎麼滴,用法介紹無力吐槽。
不相信的,直接百度看看,再回頭對比我這裡的講解。下面全代碼注釋。
例子不會舉太多,但是,我保證,看懂了這一個,其他的絕對會用。
1 View.OnClickListener count = new View.OnClickListener() { 2 @Override 3 public void onClick(View v) { 4 //m1、n1用於直接由Sring 轉為 int 判斷輸入的合法性,不作運算 5 int m1,n1; 6 //BigDecimal有很多個初始化方法,我這裡列舉一個,在初始化類對象的同時,傳入數字字串,此時的對象值為該數字 7 //下面的 m、n 都是 1 ,因為我的這個監聽事件的運算是從 1 開始的。 8 9 BigDecimal m = new BigDecimal("1");10 BigDecimal n = new BigDecimal("1");11 12 BigDecimal result_2 = new BigDecimal("1");//這個用來儲存 m!/(m-n)!n! 中的 m-n 階乘 從1開始13 Toast.makeText(MyActivity.this,save_m+"***"+save_switch+"///"+save_n,Toast.LENGTH_LONG).show();14 15 m1 = Integer.parseInt(save_m);//save_m 和 下面的 save_n 都是 editText 輸入擷取的值16 n1 = Integer.parseInt(save_n);17 if(m1<0 || n1<0 || m1 < n1){18 t3.setText("保持 m>=0,n>=0,且 m >n,組合計算請保持 m<900,n<900");19 }else {20 //太大,運算速度有延遲,幾千億的數運算,電腦都要幾個秒21 if(save_switch.equals("組合") || n1>900 || m1>900) {22 t3.setText("組合計算請保持 m<900,n<900");23 }else {24 if (save_switch.equals("組合")) {25 //long result_1 = 1, result_2 = 1, result = 1;//long 都不夠用26 for (int i = 1; i <= m1; i++) {27 Log.d("tag", "before * m is " + m + ":" + "i is " + i);28 29 //BigDecimal 類方法,乘法,這裡的乘包括同門的加、減、除,不再是+、-、*、/30 //常用乘法: multiply(BigDecimal xx),四個都有傳回值,傳回型別也是 BigDecimal31 //下面這行是個例子32 m = m.multiply(BigDecimal.valueOf(i));//每次乘 i33 // 我上面的 BigDecimal.valueOf(i) 這個是用於把 int 類型的 i轉為 BigDecimal 對象傳入34 35 if (i <= n1) {36 Log.d("tag", "before * n is " + n + ":" + "i is " + i);37 n = n.multiply(BigDecimal.valueOf(i));38 }39 if (i <= (m1 - n1)) {40 Log.d("tag", "before * result_2 is " + result_2 + ":" + "i is " + i);41 result_2 = result_2.multiply(BigDecimal.valueOf(i));42 }43 Log.d("tag", "-" + result_2);44 }45 Log.d("tag", "m->" + m);46 Log.d("tag", "n->" + n);47 Log.d("tag", "r->" + result_2);48 // 除法: divide(),用法參照上面的乘法49 m = m.divide(n.multiply(result_2));50 t3.setText("Result is:" + m + ";");51 }52 }53 if(save_switch.equals("排列")){54 Toast.makeText(MyActivity.this,"789798",Toast.LENGTH_LONG).show();55 //int result_1 = 1, result_2 = 1, result = 1;56 for (int i = 1; i <= m1; i++) {57 // Log.d("tag","is->"+result);58 m = m.multiply(BigDecimal.valueOf(i));59 Log.d("tag","i->"+i);60 if (i <= (m1 - n1)) {61 result_2 = result_2.multiply(BigDecimal.valueOf(i));62 }63 }64 //t3.setText("For double is:" + result + ";" + "For FenShu is:" + result_2);65 m = m.divide(result_2);66 t3.setText("Result is:" + m + ";");67 }68 }69 }70 };
BigDecimal 可運算的 數級 可 達到 70多位,可能更多,十進位哦。
java 大資料處理類 BigDecimal 解析