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多位,可能更多,十进制哦。

时间: 2024-08-26 14:07:04

java 大数据处理类 BigDecimal 解析的相关文章

java笔记--String类对象解析与运用

1.String中的equals和==的区别 String是对象而非基本数据类型,不能使用"=="来判断两个字符串是否相当, 判断两个字符串内容是否相同用equals(); 判断两个字符串内存地址是否相同用"==" 2.startsWith(String str): 判断字符串是否以str为前缀 3.endsWith(String str): 判断字符串是否以str为后缀 4.String 字符串的比较: 1).compareTo()和compareToIgnore

java大数据处理调优

从总体上来看,对于大型网站,比如门户网站,在面对大量用户访问.高并发请求方面,基本的解决方案集中在这样几个环节:1.首先需要解决网络带宽和Web请求的高并发,需要合理的加大服务器和带宽的投入,并且需要充分的利用系统中软件.硬件的缓存机制,将能缓存的内容都进行缓存存储,减少计算层和存储层的压力. 2.其次需要对业务服务器和业务支撑服务器进行合理的分层,并且采用并行计算和分布式算法对大量计算进行处理,并且在开发的过程中需要采用Java SDK中并发包(Concurrency)进行编码实现. 3.存储

java 大数据处理之内存溢出解决办法(一)

http://www.cnblogs.com/a757956132/p/4644910.html http://my.oschina.net/songhongxu/blog/209951 一.内存溢出类型 1.java.lang.OutOfMemoryError: PermGen space JVM管理两种类型的内存,堆和非堆.堆是给开发人员用的上面说的就是,是在JVM启动时创建:非堆是留给JVM自己用的,用来存放类的信息的.它和堆不同,运行期内GC不会释放空间.如果web app用了大量的第三

Java 8 Optional类深度解析

身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只有在非空的前提下才能将其作为其他方法的参数.这正是一些类似Guava的外部API试图解决的问题.一些JVM编程语言比如Scala.Ceylon等已经将对在核心API中解决了这个问题.在我的前一篇文章中,介绍了Scala是如何解决了这个问题. 新版本的Java,比如Java 8引入了一个新的Optional类.Optional类的Javadoc

[转]Java 8 Optional类深度解析(null处理)

原文链接:http://www.importnew.com/6675.html 本文由 ImportNew - 高俊阳 翻译自 javacodegeeks.欢迎加入翻译小组.转载请见文末要求. 身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法.我们首先要判断这个返回值是否为null,只有在非空的前提下才能将其作为其他方法的参数.这正是一些类似Guava的外部API试图解决的问题.一些JVM编程语言比如Scala.Ceylon等已经将

JAVA大数据处理题

1. 给定a.b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a.b文件共同的url? 方案1:可以估计每个文件安的大小为50G×64=320G,远远大于内存限制的4G.所以不可能将其完全加载到内存中处理.考虑采取分而治之的方法. s 遍历文件a,对每个url求取 ,然后根据所取得的值将url分别存储到1000个小文件(记为 )中.这样每个小文件的大约为300M. s 遍历文件b,采取和a相同的方式将url分别存储到1000各小文件(记为 ).这样处理后,所有可

Java大数处理类:BigInteger类和BigDecimal类

当我们要处理非常大的数据时,平常用的数据类型已不足以表示,在Java中有两个类BigInteger和BigDecimal分别表示大整数类和大浮点数类,这两个类在理论上只要计算机内存足够大就能够表示无线大的数.它们都在java.math.*包中,我们可以在API文档中进行查看: Java API 1.6 中文在线帮助文档 http://www.yq1012.com/api/ 实例: 1 import java.math.BigDecimal; 2 import java.math.BigInteg

Java集合---Array类源码解析

Java集合---Array类源码解析              ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Primitive(8种基本类型)和Object两大类. 基本类型:采用调优的快速排序: 对象类型:采用改进的归并排序. 1.对于基本类型源码分析如下(以int[]为例): Java对Primitive(int,float等原型数据)数组采用快速排序,对Object对象数组采用归并排序.对这一区别,sun在

java中商业数据计算时用到的类BigDecimal和DecimalFormat

1.引言 借用<Effactive Java>这本书中的话,float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的.然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合.但是,商业计算往往要求结果精确,这时候BigDecimal就派上大用场啦. 2.BigDecimal简介 BigDecimal 由任意精度的整数非标度值 和32 位的整数标度 (scale) 组成.如果为零或正数