关于高精度正整数计算的JAVA实现
2006-04-15 19:47
561 查看
所谓高精度就是位数要求比较高的数,是我们通常使用的数据类型无法满足的数,因为它的位数要求超出了我们的数据类型的一般化的定义。我们经常会遇到这样的数字,例如我们国家的身分证号,它是18位的,在Excle中常常用科学记数法所表示,虽然可以进行记录,但是这和我们通常的使用方法不一致,在使用上造成了很大的麻烦。我们被迫使用文本方式记录这样的数据,但是当我们进行二分法查找或者排序时,又遇到了文本和数字的转换问题,十分的让人头疼。
我们用高精度正整数就可以解决这个问题,达到双赢的目的,我们可以在显示时让它是18位的,在排序或查找时是当作数字处理的。而且位数大到常用数据类型无法满足的时候,高精度数的优势就充分体现出来了,别人做不到的我能做。
高精度的存储就是利用一个数组来存储一个高精度数,这样无论多大的数,只要分配相应的数组空间就可以解决了,然后在记录一下数组实际被使用的长度,我们的高精度数就存储进计算机了,就是这么简单。接下来我们要解决的就是计算的问题,想必大家都是从小学学竖式计算起家的,我们对高精度数的计算就是模仿这个过程,而高精度数存储是用的数组,这给我们的按位计算提供了很大的方便。
我们现在就可以动手写写了,在完成后我觉得这样做比较浪费空间,因为定义了定长的数组,而考虑到数据的位数又不敢定义的太小,造成空间的浪费。我们可以利用链表来巧妙的解决这一问题,达到用多大的空间就申请多大的目的。另一方法,也可以利用数组先声明不分配空间,到使用时获得数组长度来分配空间的方法来实现。所谓殊途同归,思想都是把数组定义为可变长度的。
另一方面我们关心的就是计算速度问题,用到数组就很难不用到循环,它们就好象是微软的OS总要捆绑IE一样。循环是程序的耗时大户,循环次数少了,程序运行时间也会随之降下来。我们可以利用这个特性,并充分利用整型数据的存储空间,把数组中的数定义成10000(整型数为两字节长时)进制的,多多利用语言自己的计算方法削减我们要手工做的循环。我们知道底层的代码执行速度要远远快于上层,我们在特殊的场合甚至可以直接用硬件来实现这个思想,这时的计算速度是不可想像的。还有如果数字都是十分大的话,我们可以把整个数组定义为长型的,这样我们可以获得更大的进制来削减循环次数。
下面是我写的一个简单的程序,只是实现了部分功能,还没有优化运行速度和空间占用,希望抛砖引玉吧:
/**
*Name:HighInteger.java
*Author:Richard
*Date:Apr-15,2006
*Version:1.0.0.0
*=====================
*usetocaculateverygreatinteger
*/
publicclassHighInteger{
protectedintlen;
protectedintS[];
protectedfinalintMAXLEN=100;
/**
*constructmethod
*/
publicHighInteger(){
len=0;
S=newint[MAXLEN];
}
/**
*reloadtheconstructmethod
*/
publicHighInteger(intplen,intpS[]){
len=plen;
S=newint[MAXLEN];
for(inti=0;i<plen;i++)
S[plen-1-i]=pS[i];
}
/**
*setlenofHighInteger
*/
publicvoidsetLen(intplen){
len=plen;
}
/**
*setarraynamedSinHighInteger
*/
publicvoidsetS(intpS[]){
len=pS.length;
for(inti=0;i<pS.length;i++)
S[pS.length-1-i]=pS[i];
}
/**
*settheelementofarraynamedSinHighInteger
*indexisbetween0andthelen-1
*/
protectedvoidsetSElement(intindex,intvalue){
S[index]=value;
}
/**
*settheelementofarraythatusedasinterface
*indexisbetween1andthelen
*/
publicvoidsetElement(intindex,intvalue){
S[this.getLen()-index]=value;
}
/**
*getlenofHighInteger
*/
publicintgetLen(){
returnlen;
}
/**
*gettheelementofarraynamedSinHighInteger
*indexisbetween0andthelen-1
*/
protectedintgetSElement(intindex){
returnS[index];
}
/**
*gettheelementofarraythatusedasinterface
*indexisbetween1andthelen
*/
publicintgetElement(intindex){
returnS[this.getLen()-index];
}
/**
*AddtwogreatintegerandreturnasHighInteger
*/
publicstaticHighIntegerHighIntegerAdd(HighIntegerparm1,HighIntegerparm2){
HighIntegerresult=newHighInteger();
result.setLen(parm1.getLen()>parm2.getLen()?parm1.getLen():parm2.getLen());
for(inti=0;i<result.getLen();i++){
result.setSElement(i,result.getSElement(i)+parm1.getSElement(i)+parm2.getSElement(i));
if(result.getSElement(i)>=10){
result.setSElement(i,result.S[i]-10);
result.setSElement(i+1,result.getSElement(i+1)+1);
}
}
if(result.getSElement(result.getLen())>=1)
result.setLen(result.getLen()+1);
returnresult;
}
/**
*MinustwogreatintegerandreturnasHighInteger
*/
publicstaticHighIntegerHighIntegerMinus(HighIntegerparm1,HighIntegerparm2){
HighIntegerresult=newHighInteger();
intlen=parm1.getLen();
result.setLen(len);
for(inti=0;i<len;i++){
result.setSElement(i,result.getSElement(i)+parm1.getSElement(i)-parm2.getSElement(i));
if(result.getSElement(i)<0){
result.setSElement(i,result.getSElement(i)+10);
result.setSElement(i+1,result.getSElement(i+1)-1);
}
}
while((len>1)&&(result.getSElement(len)>=1))len--;
result.setLen(len);
returnresult;
}
/**
*MultitwogreatintegerandreturnasHighInteger
*/
publicstaticHighIntegerHighIntegerMulti(HighIntegerparm1,HighIntegerparm2){
HighIntegerresult=newHighInteger();
intlen=parm1.getLen()+parm2.getLen();
for(inti=0;i<parm1.getLen();i++){
for(intj=0;j<parm2.getLen();j++){
result.setSElement(i+j,result.getSElement(i+j)+parm1.getSElement(i)*parm2.getSElement(j));
result.setSElement(i+j+1,result.getSElement(i+j)/10);
result.setSElement(i+j,result.getSElement(i+j)%10);
}
}
while((len>1)&&(result.getSElement(len)>=1))len--;
result.setLen(len);
returnresult;
}
/**
*printthegreatinteger
*/
publicvoidprintHighInteger(){
for(inti=this.getLen()-1;i>=0;i--)
System.out.print(S[i]);
System.out.println();
}
};
//==========EndClassHighInteger==========
我们用高精度正整数就可以解决这个问题,达到双赢的目的,我们可以在显示时让它是18位的,在排序或查找时是当作数字处理的。而且位数大到常用数据类型无法满足的时候,高精度数的优势就充分体现出来了,别人做不到的我能做。
高精度的存储就是利用一个数组来存储一个高精度数,这样无论多大的数,只要分配相应的数组空间就可以解决了,然后在记录一下数组实际被使用的长度,我们的高精度数就存储进计算机了,就是这么简单。接下来我们要解决的就是计算的问题,想必大家都是从小学学竖式计算起家的,我们对高精度数的计算就是模仿这个过程,而高精度数存储是用的数组,这给我们的按位计算提供了很大的方便。
我们现在就可以动手写写了,在完成后我觉得这样做比较浪费空间,因为定义了定长的数组,而考虑到数据的位数又不敢定义的太小,造成空间的浪费。我们可以利用链表来巧妙的解决这一问题,达到用多大的空间就申请多大的目的。另一方法,也可以利用数组先声明不分配空间,到使用时获得数组长度来分配空间的方法来实现。所谓殊途同归,思想都是把数组定义为可变长度的。
另一方面我们关心的就是计算速度问题,用到数组就很难不用到循环,它们就好象是微软的OS总要捆绑IE一样。循环是程序的耗时大户,循环次数少了,程序运行时间也会随之降下来。我们可以利用这个特性,并充分利用整型数据的存储空间,把数组中的数定义成10000(整型数为两字节长时)进制的,多多利用语言自己的计算方法削减我们要手工做的循环。我们知道底层的代码执行速度要远远快于上层,我们在特殊的场合甚至可以直接用硬件来实现这个思想,这时的计算速度是不可想像的。还有如果数字都是十分大的话,我们可以把整个数组定义为长型的,这样我们可以获得更大的进制来削减循环次数。
下面是我写的一个简单的程序,只是实现了部分功能,还没有优化运行速度和空间占用,希望抛砖引玉吧:
/**
*Name:HighInteger.java
*Author:Richard
*Date:Apr-15,2006
*Version:1.0.0.0
*=====================
*usetocaculateverygreatinteger
*/
publicclassHighInteger{
protectedintlen;
protectedintS[];
protectedfinalintMAXLEN=100;
/**
*constructmethod
*/
publicHighInteger(){
len=0;
S=newint[MAXLEN];
}
/**
*reloadtheconstructmethod
*/
publicHighInteger(intplen,intpS[]){
len=plen;
S=newint[MAXLEN];
for(inti=0;i<plen;i++)
S[plen-1-i]=pS[i];
}
/**
*setlenofHighInteger
*/
publicvoidsetLen(intplen){
len=plen;
}
/**
*setarraynamedSinHighInteger
*/
publicvoidsetS(intpS[]){
len=pS.length;
for(inti=0;i<pS.length;i++)
S[pS.length-1-i]=pS[i];
}
/**
*settheelementofarraynamedSinHighInteger
*indexisbetween0andthelen-1
*/
protectedvoidsetSElement(intindex,intvalue){
S[index]=value;
}
/**
*settheelementofarraythatusedasinterface
*indexisbetween1andthelen
*/
publicvoidsetElement(intindex,intvalue){
S[this.getLen()-index]=value;
}
/**
*getlenofHighInteger
*/
publicintgetLen(){
returnlen;
}
/**
*gettheelementofarraynamedSinHighInteger
*indexisbetween0andthelen-1
*/
protectedintgetSElement(intindex){
returnS[index];
}
/**
*gettheelementofarraythatusedasinterface
*indexisbetween1andthelen
*/
publicintgetElement(intindex){
returnS[this.getLen()-index];
}
/**
*AddtwogreatintegerandreturnasHighInteger
*/
publicstaticHighIntegerHighIntegerAdd(HighIntegerparm1,HighIntegerparm2){
HighIntegerresult=newHighInteger();
result.setLen(parm1.getLen()>parm2.getLen()?parm1.getLen():parm2.getLen());
for(inti=0;i<result.getLen();i++){
result.setSElement(i,result.getSElement(i)+parm1.getSElement(i)+parm2.getSElement(i));
if(result.getSElement(i)>=10){
result.setSElement(i,result.S[i]-10);
result.setSElement(i+1,result.getSElement(i+1)+1);
}
}
if(result.getSElement(result.getLen())>=1)
result.setLen(result.getLen()+1);
returnresult;
}
/**
*MinustwogreatintegerandreturnasHighInteger
*/
publicstaticHighIntegerHighIntegerMinus(HighIntegerparm1,HighIntegerparm2){
HighIntegerresult=newHighInteger();
intlen=parm1.getLen();
result.setLen(len);
for(inti=0;i<len;i++){
result.setSElement(i,result.getSElement(i)+parm1.getSElement(i)-parm2.getSElement(i));
if(result.getSElement(i)<0){
result.setSElement(i,result.getSElement(i)+10);
result.setSElement(i+1,result.getSElement(i+1)-1);
}
}
while((len>1)&&(result.getSElement(len)>=1))len--;
result.setLen(len);
returnresult;
}
/**
*MultitwogreatintegerandreturnasHighInteger
*/
publicstaticHighIntegerHighIntegerMulti(HighIntegerparm1,HighIntegerparm2){
HighIntegerresult=newHighInteger();
intlen=parm1.getLen()+parm2.getLen();
for(inti=0;i<parm1.getLen();i++){
for(intj=0;j<parm2.getLen();j++){
result.setSElement(i+j,result.getSElement(i+j)+parm1.getSElement(i)*parm2.getSElement(j));
result.setSElement(i+j+1,result.getSElement(i+j)/10);
result.setSElement(i+j,result.getSElement(i+j)%10);
}
}
while((len>1)&&(result.getSElement(len)>=1))len--;
result.setLen(len);
returnresult;
}
/**
*printthegreatinteger
*/
publicvoidprintHighInteger(){
for(inti=this.getLen()-1;i>=0;i--)
System.out.print(S[i]);
System.out.println();
}
};
//==========EndClassHighInteger==========
相关文章推荐
- Java大整数实现计算catalan数
- java 之BigInteger类实现计算大整数的阶乘
- 关于矩阵计算的java 代码实现----笔记
- 关于18位身份证号码最后一位计算(Java实现)
- 最短路径--高精度整数(java实现)
- java实现双栈计算整数表达式
- 使用数组实现过大的非零整数的加法计算(java)
- java实现计算两个整数的最大公约数代码及附图
- 商业计算中Java高精度计算BigDecimal类
- 关于openstack部分计算节点无法实现热迁移问题描述
- Java做高精度计算(BigDecimal类)
- java的WEB应用关于UDDI协议的实现
- [LeetCode][13]Roman to Integer解析 罗马字符转int类型关于栈的常数实现-Java实现
- Java实现输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。
- 根据两点经纬度计算距离和角度——java实现
- 关于java 的科学计算算法(前,中,后缀表达式的转换)——计算器制作的心得
- java与接口实现素数个数计算
- java实现——2001计算两点间的距离
- java实现输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径