关于高精度正整数计算的JAVA实现

 

 

      所谓高精度就是位数要求比较高的数,是我们通常使用的数据类型无法满足的数,因为它的位数要求超出了我们的数据类型的一般化的定义。我们经常会遇到这样的数字,例如我们国家的身分证号,它是18位的,在Excle中常常用科学记数法所表示,虽然可以进行记录,但是这和我们通常的使用方法不一致,在使用上造成了很大的麻烦。我们被迫使用文本方式记录这样的数据,但是当我们进行二分法查找或者排序时,又遇到了文本和数字的转换问题,十分的让人头疼。
     我们用高精度正整数就可以解决这个问题,达到双赢的目的,我们可以在显示时让它是18位的,在排序或查找时是当作数字处理的。而且位数大到常用数据类型无法满足的时候,高精度数的优势就充分体现出来了,别人做不到的我能做。
     高精度的存储就是利用一个数组来存储一个高精度数,这样无论多大的数,只要分配相应的数组空间就可以解决了,然后在记录一下数组实际被使用的长度,我们的高精度数就存储进计算机了,就是这么简单。接下来我们要解决的就是计算的问题,想必大家都是从小学学竖式计算起家的,我们对高精度数的计算就是模仿这个过程,而高精度数存储是用的数组,这给我们的按位计算提供了很大的方便。
     我们现在就可以动手写写了,在完成后我觉得这样做比较浪费空间,因为定义了定长的数组,而考虑到数据的位数又不敢定义的太小,造成空间的浪费。我们可以利用链表来巧妙的解决这一问题,达到用多大的空间就申请多大的目的。另一方法,也可以利用数组先声明不分配空间,到使用时获得数组长度来分配空间的方法来实现。所谓殊途同归,思想都是把数组定义为可变长度的。
     另一方面我们关心的就是计算速度问题,用到数组就很难不用到循环,它们就好象是微软的OS总要捆绑IE一样。循环是程序的耗时大户,循环次数少了,程序运行时间也会随之降下来。我们可以利用这个特性,并充分利用整型数据的存储空间,把数组中的数定义成10000(整型数为两字节长时)进制的,多多利用语言自己的计算方法削减我们要手工做的循环。我们知道底层的代码执行速度要远远快于上层,我们在特殊的场合甚至可以直接用硬件来实现这个思想,这时的计算速度是不可想像的。还有如果数字都是十分大的话,我们可以把整个数组定义为长型的,这样我们可以获得更大的进制来削减循环次数。
     下面是我写的一个简单的程序,只是实现了部分功能,还没有优化运行速度和空间占用,希望抛砖引玉吧:
 

/**
 *Name:HighInteger.java
 *Author:Richard
 *Date:Apr-15,2006
 *Version:1.0.0.0
 *=====================
 *use to caculate very great integer
 */
 
 public class HighInteger{
  
  protected int len;
  protected int S[];
  protected final int MAXLEN = 100;
  
/**
 *construct method
 */
 public HighInteger(){
  
  len = 0;
  S = new int[MAXLEN];
 }
 
/**
 *reload the construct method
 */
 public HighInteger(int plen, int pS[]){

  len = plen;
  S = new int[MAXLEN];
  for(int i=0; i<plen; i++)
   S[plen-1-i] = pS[i];
 }
 
/**
 *set len of HighInteger
 */
 public void setLen(int plen){
  
  len = plen;
 }
 
/**
 *set array named S in HighInteger
 */
 public void setS(int pS[]){

  len = pS.length;
  for(int i=0; i<pS.length; i++)
   S[pS.length-1-i] = pS[i];
 }
 
/**
 *set the element of array named S in HighInteger
 *index is between 0 and the len-1
 */
 protected void setSElement(int index, int value){
  
  S[index] = value;
 }
 
/**
 *set the element of array that used as interface
 *index is between 1 and the len
 */
  public void setElement(int index, int value){
   
   S[this.getLen()-index] = value;
  }
 
/**
 *get len of HighInteger
 */
 public int getLen(){
  
  return len;
 }
 
/**
 *get the element of array named S in HighInteger
 *index is between 0 and the len-1
 */
 protected int getSElement(int index){
  
  return S[index];
 }

/**
 *get the element of array that used as interface
 *index is between 1 and the len
 */
  public int getElement(int index){
 
   return S[this.getLen()-index];
  }
 
/**
 *Add two great integer and return as HighInteger
 */
 public static HighInteger HighIntegerAdd(HighInteger parm1, HighInteger parm2){
  
  HighInteger result = new HighInteger();
  
  result.setLen(parm1.getLen()>parm2.getLen() ? parm1.getLen() : parm2.getLen());
  
  for(int i=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);
   
  return result;
 }
 
/**
 *Minus two great integer and return as HighInteger
 */
 public static HighInteger HighIntegerMinus(HighInteger parm1, HighInteger parm2){
  
  HighInteger result = new HighInteger();
  
  int len = parm1.getLen();
  result.setLen(len);
  
  for(int i=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);
  
  return result;
 }

/**
 *Multi two great integer and return as HighInteger
 */
 public static HighInteger HighIntegerMulti(HighInteger parm1, HighInteger parm2){
  
  HighInteger result = new HighInteger();
  
  int len = parm1.getLen()+parm2.getLen();
  
  for(int i=0; i<parm1.getLen(); i++){
   for(int j=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);

  return result;
 }
 
/**
 *print the great integer
 */
 public void printHighInteger(){
  
  for(int i=this.getLen()-1; i>=0; i--)
   System.out.print(S[i]);
  System.out.println();
 }
 };
 //==========End Class HighInteger==========

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值