java 大数据处理类 BigDecimal 解析

这两天,由于我的必修课概率论里经常要用到排列组合的计算,感觉很麻烦,加上现代智能手机的计算器是没有这方面功能的。

所以,就自己动手写了个安卓的 排列组合 计算器,用了一天,发现有很大的问题,阶乘达百亿级别的数,程序将不再运行。

我这里举个例子,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),四个都有返回值,返回类型也是 BigDecimal
31                             //下面这行是个例子
32                             m = m.multiply(BigDecimal.valueOf(i));//每次乘 i
33                             // 我上面的 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多位,可能更多,十进制哦。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android干货

安卓开发_浅谈ListView(SimpleAdapter数组适配器)

25410
来自专栏Android开发指南

2.ui

3689
来自专栏微信公众号:Java团长

一个经典例子让你彻彻底底理解Java回调机制

以前不理解什么叫回调,天天听人家说加一个回调方法啥的,心里想我草,什么叫回调方法啊?然后自己就在网上找啊找啊找,找了很多也不是很明白,现在知道了,所谓回调:就是...

1154
来自专栏菩提树下的杨过

Reactor 3 学习笔记(2)

上面的代码,reduce相当于把1到10累加求和,reduceWith则是先指定一个起始值,然后在这个起始值基础上再累加。(tips: 除了累加,还可以做阶乘)...

1002
来自专栏JackieZheng

漫谈可视化Prefuse(二)---一分钟学会Prefuse

  前篇《漫谈可视化Prefuse(一)---从SQL Server数据库读取数据》主要介绍了prefuse如何连接数据库sql server并读取数据进行可视...

2096
来自专栏swag code

Calendar类-set()方法的延时操作

set(f,value)方法将日历字段f更改为value,此外还设置了一个内部成员变量,

502
来自专栏非著名程序员

关于 Android 实现滑动返回的几种方法总结

关于 Android 实现滑动返回的方法,网上有很多种,实现的方式也都各不一样。有用 SwipeBackLayout 开源库的,有用 SlidingPaneLa...

3519
来自专栏技术小黑屋

Android中Handler引起的内存泄露

在Android常用编程中,Handler在进行异步操作并处理返回结果时经常被使用。通常我们的代码会这样实现。

652
来自专栏吴小龙同學

设计模式之观察者模式

观察者模式 观察者模式(Observer pattern),定义了对象间一种一对多的依赖关系,当 被观察者 状态发生变化,它的 观察者 们会收到通知并自动更新。...

31711
来自专栏向治洪

android内存优化

Android的应用被限制为最多占用16m的内存,至少在T-Mobile G1上是这样的(当然现在已经有几百兆的内存可以用了——译者注)。它包括电话本身占用的和...

1747

扫码关注云+社区