学以致用——Java源码——自定义40位长整数类及测试类(通过字符串解析构造、静态方法求和等)(Huge Integer Class)

2020/02/19补记:

使用Java BigInteger类测试通过。(仅限两个大整数都为40位的情况,且第一个数字大于第二个数字。现在发现,自定义的这个类的设计更像是面向过程设计而不是面向对象设计。)

测试结果如下:

b1: 3456789012345678901234567890123456789012, b2:2345678901234567890123456789012345678901

加法操作:5802467913580246791358024679135802467913

减法操作:1111110111111111011111111101111111110111

乘法操作:8108517052278739222374662673952145142565060698363359281084621249233290657035812

除法操作:0

最大数:3456789012345678901234567890123456789012

最小数:2345678901234567890123456789012345678901

商是:1;余数是:1111110111111111011111111101111111110111

等价性是:false

比较操作: b1>b2

参考文章:

Java核心技术——Java BigInteger类(大整数类) 

-------------------------------------------------------------------------------------------------------------------

以下为正文:

功能:

1. 使用字符串解析构建一个40位的整数

2. 实现加减运算及其他一些方法(比较大小等)

参考文章:

自定义40位大整数类及测试类(Define a huge integer and implement its arithmetic operation),

https://blog.csdn.net/hpdlzu80100/article/details/2318646

测试结果:

长整数33456789012345678901234567890123456789012

长整数42345678901234567890123456789012345678901

长整数3和长整数4不相等(使用isEqualTo方法)

长整数3和长整数4不相等(使用isNotEqualTo方法)

长整数3大于长整数4(使用isGreaterThan方法)

长整数3大于长整数4(使用isLessThan方法)

长整数3大于等于长整数4(使用isGreaterThanOrEqualTo方法)

长整数3大于长整数4(使用isLessThanOrEqualTo方法)

长整数3和长整数4的和为:

Huge Integer: 5802467913580246791358024679135802467913

长整数3和长整数4的差为:

Huge Integer: 1111110111111111011111111101111111110111

 

长整数32345678901234567890123456789012345678901

长整数42345678901234567890123456789012345678901

长整数3和长整数4相等(使用isEqualTo方法)

长整数3和长整数4相等(使用isNotEqualTo方法)

长整数3小于等于长整数4(使用isGreaterThan方法)

长整数3大于等于长整数4(使用isLessThan方法)

长整数3大于等于长整数4(使用isGreaterThanOrEqualTo方法)

长整数3小于等于长整数4(使用isLessThanOrEqualTo方法)

长整数3和长整数4的和为:

 

长整数32345678901234567890123456789012345678901

长整数3和长整数4的和为:4691357802469135780246913578024691357802

长整数3和长整数4的差为:

Huge Integer: 0000000000000000000000000000000000000000

长整数3等于零

 

代码:

1. 实体类HugeInteger

//JHTP Exercise 8.16: Huge Integer Class
//by pandenghuang@163.com
/**
 * 8.16 (Huge Integer Class) Create a class HugeInteger which uses a 40-element
 * array of digits to store integers as large as 40 digits each. Provide methods
 * parse, toString, add and subtract. Method parse should receive a String,
 * extract each digit using method charAt and place the integer equivalent of
 * each digit into the integer array. For comparing HugeInteger objects, provide
 * the following methods: isEqualTo, isNotEqualTo, isGreaterThan, isLessThan,
 * isGreaterThanOrEqualTo and isLessThanOrEqualTo. Each of these is a predicate
 * method that returns true if the relationship holds between the two
 * HugeInteger objects and returns false if the relationship does not hold.
 * Provide a predicate method isZero. If you feel ambitious, also provide
 * methods multiply, divide and remainder. [Note: Primitive boolean values can
 * be output as the word “true” or the word “false” with format specifier %b.]
 * 
 * @author pandenghuang@163.com
 *
 */
public class HugeInteger {
	final static int SIZE = 40;	//自定义长整数的位数
    private int[ ] singleDigits=new int[SIZE];
    private int[ ] carry=new int[SIZE];
    
    /**
     * 无参构造函数(所有位初始化为0)
     */
    public HugeInteger()
    {
        for (int i=0;i<singleDigits.length;i++)
            singleDigits[i]=0;
    }
    /**
     * 使用HugeInteger构造一个HugeInteger(复制)
     * @param hugeI
     */
    public HugeInteger(int[] hugeI)
    {
        for (int i=0;i<singleDigits.length;i++)
            singleDigits[i]=hugeI[i];
    }
    
    /**
     * 解析一个字符串为HugeInteger
     * @param hugeI
     */
    public static HugeInteger parse(String hugeIntegerText)
    {
    	int[ ] singleDigits=new int[SIZE];
        for (int i=0;i<SIZE;i++)
            singleDigits[i]=Integer.parseInt(String.valueOf(hugeIntegerText.charAt(i)));
        
        return new HugeInteger(singleDigits);
    }
    
    
    /**
     * 重置(所有位初始化为0)
     * @param hugeI
     */
    public void reset()
    {
        for (int i=0;i<singleDigits.length;i++)
            singleDigits[i]=0;
    }
    
    
    /**
     * 返回大整数的格式化输出字符串
     */
    public String toString()
    {    
    	String s="";
        for (int i=0;i<singleDigits.length;i++)
        	s += singleDigits[i];
        
        return String.format("%s",s);
    }
    
    public void output()
    {    System.out.print("Huge Integer: ");
        for (int i=0;i<singleDigits.length;i++)
            System.out.print(singleDigits[i]);
            System.out.println();
    }
    
    public void add(HugeInteger HI)
    {  int[] repository=new int[41];
        for (int i=singleDigits.length-1;i>=0;i--) 
            {
            if (i<singleDigits.length-1)
            carry[i]=(singleDigits[i]+HI.singleDigits[i]+carry[i+1])/10;
            else
                carry[i]=(singleDigits[i]+HI.singleDigits[i])/10;
            if (i<singleDigits.length-1)
            repository[i+1]=(singleDigits[i]+HI.singleDigits[i]+carry[i+1])%10;
            else 
                repository[i+1]=(singleDigits[i]+HI.singleDigits[i])%10;
            }
        repository[0]=(carry[1]+singleDigits[0]+HI.singleDigits[0])/10;
           if (repository[0]==1)
               {
               System.out.print("Overflow Error!!! ");
               reset();
               }
           else
               for (int i=0;i<singleDigits.length;i++ )
                  singleDigits[i]=repository[i+1];
           
    }
    
    /**
     * 静态方法(类方法),2019年1月2日重写
     * @param hi1 hugeInteger1
     * @param hi2 hugeInteger2
     * @return
     */
    public static HugeInteger add(HugeInteger hi1, HugeInteger hi2)
    {  int[] repository=new int[SIZE+1];
       int[] carry = new int[SIZE];  //进位
       int[] result = new int[SIZE];
        for (int i=SIZE-1;i>=0;i--)   //从低位(右侧)开始计算
            {
            if (i<SIZE-1) //最低位以外的位上的进位要考虑上一位上的进位
            carry[i]=(hi1.singleDigits[i]+hi2.singleDigits[i]+carry[i+1])/10;
            else //最低位上的进位(i=SIZE-1)
                carry[i]=(hi1.singleDigits[i]+hi2.singleDigits[i])/10;
            
            if (i<SIZE-1) //最低位以外的位上的求和的结果(要考虑上一位上的进位)
            repository[i+1]=(hi1.singleDigits[i]+hi2.singleDigits[i]+carry[i+1])%10;
            else //最低位求和的结果(i=SIZE-1)
                repository[i+1]=(hi1.singleDigits[i]+hi2.singleDigits[i])%10;
            }
        repository[0]=(carry[1]+hi1.singleDigits[0]+hi2.singleDigits[0])/10;
           if (repository[0]==1)
               {
               System.out.print("Overflow Error!!! ");
               return new HugeInteger();
               }
           else {
               for (int i=0;i<SIZE;i++) 
                  result[i]=repository[i+1];  //将计算结果由高位(对应数组低位)赋值给结果数组
                  return new HugeInteger(result);}
    }
    
    public boolean substract(HugeInteger HI)
    {
        boolean underflowFlag=false;
        int[] repository=new int[41];
        for (int i=singleDigits.length-1;i>=1;i--)
        {
        if (singleDigits[i]-HI.singleDigits[i]>=0)
            repository[i+1]=singleDigits[i]-HI.singleDigits[i];
        else
        {
            repository[i+1]=10+singleDigits[i]-HI.singleDigits[i];
            singleDigits[i-1]-=1;
        }
        }
        
        repository[0]=singleDigits[0]-HI.singleDigits[0];
         if (repository[0]<0)
           {
           System.out.print("Overflow Error!!! ");
           reset();
           return(underflowFlag=true);
           }
       else
       {   repository[1]=singleDigits[0]-HI.singleDigits[0];
           for (int i=0;i<singleDigits.length;i++ )
               singleDigits[i]=repository[i+1];
           return(underflowFlag);
         }
    }
    
    public boolean isEqualTo(HugeInteger HI){
        boolean equalFlag=true;
        for (int i=0;i<singleDigits.length;i++)
            if (singleDigits[i]!=HI.singleDigits[i])
            {equalFlag=false;
            break;
            }
        return equalFlag;
    }
    
    public boolean isNotEqualTo(HugeInteger HI){
        
        
        return !isEqualTo(HI);
    }
    
    public boolean isGreaterThan(HugeInteger hi){
        boolean greaterThanFlag=false;
        for (int i=0;i<singleDigits.length;i++)
            {
            if (singleDigits[i]>hi.singleDigits[i])
                {greaterThanFlag=true;
                break;}
            else if (singleDigits[i]<hi.singleDigits[i])
                    {greaterThanFlag=false;
                    break;}
            }
    return greaterThanFlag;
    }
    
    public boolean isLessThan(HugeInteger HI){
        boolean lessThanFlag=false;
        for (int i=0;i<singleDigits.length;i++)
        { if (singleDigits[i]<HI.singleDigits[i])
            {lessThanFlag=true;
            break;}
            else if (singleDigits[i]>HI.singleDigits[i])
            {lessThanFlag=false;
            break;}
            }
        return lessThanFlag;
    }
    
    public boolean isGreaterThanOrEqualTo(HugeInteger HI){
        
        return !isLessThan(HI);
    }
    
    public boolean isLessThanOrEqualTo(HugeInteger HI){
    
        return !isGreaterThan(HI);
        
    }
    
    public boolean isZero(){
        boolean zeroFlag=false;
        int tempSum=0;
        for (int i=0;i<singleDigits.length;i++)
            tempSum+=singleDigits[i];
            if (tempSum==0)
                zeroFlag=true;
        return zeroFlag;
    }
}

2. 测试类

//JHTP Exercise 8.15: Rational Numbers
//by pandenghuang@163.com
/**
* 8.16 (Huge Integer Class) Create a class HugeInteger which uses a 40-element
* array of digits to store integers as large as 40 digits each. Provide methods
* parse, toString, add and subtract. Method parse should receive a String,
* extract each digit using method charAt and place the integer equivalent of
* each digit into the integer array. For comparing HugeInteger objects, provide
* the following methods: isEqualTo, isNotEqualTo, isGreaterThan, isLessThan,
* isGreaterThanOrEqualTo and isLessThanOrEqualTo. Each of these is a predicate
* method that returns true if the relationship holds between the two
* HugeInteger objects and returns false if the relationship does not hold.
* Provide a predicate method isZero. If you feel ambitious, also provide
* methods multiply, divide and remainder. [Note: Primitive boolean values can
* be output as the word “true” or the word “false” with format specifier %b.]
* 
* @author pandenghuang@163.com
*
*/

public class HugeIntegerTest{
	
    public static void main(String[] args)
    {
    	
//
//        int[] initializer1=new int[40];
//        for (int i=0;i<40;i++)
//            initializer1[i]=(int)(10*Math.random());
//           
//        int[] initializer2=new int[40];
//        for (int j=0;j<40;j++)
//            initializer2[j]=(int)(10*Math.random());
//        
//        
//        
//        HugeInteger HI1=new HugeInteger(initializer1);
//        HugeInteger HI2=new HugeInteger(initializer2);
//        
//        
//        HI1.output();
//        HI2.output();
//        System.out.println();
//        
//
//        
//        
//        System.out.println("These two huge integers are equal: "+HI1.isEqualTo(HI2));
//        System.out.println("These two huge integers are not equal: "+HI1.isNotEqualTo(HI2));
//        System.out.println("1st huge integer is larger than 2nd: "+HI1.isGreaterThan(HI2));
//        System.out.println("1st huge integer is less than 2nd: "+HI1.isLessThan(HI2));
//        System.out.println("1st huge integer is larger than or equal to 2nd: "+
//                HI1.isGreaterThanOrEqualTo(HI2));
//        System.out.println("1st huge integer is less than or equal to 2nd: "+
//                HI1.isLessThanOrEqualTo(HI2));
//        HI1.add(HI2);
//        System.out.print("The sum is: ");
//        HI1.output();
//        HI1.substract(HI2);
//        HI1.substract(HI2);
//        System.out.print("The difference is: ");
//        HI1.output();
//        HI1.add(HI2);
        
    	HugeInteger hi3 = HugeInteger.parse("3456789012345678901234567890123456789012");
    	HugeInteger hi4 = HugeInteger.parse("2345678901234567890123456789012345678901");
        System.out.printf("长整数3:%s%n",hi3);
        System.out.printf("长整数4:%s%n",hi4);
        System.out.printf("长整数3和长整数4%s相等(使用isEqualTo方法)%n",hi3.isEqualTo(hi4)?"":"不");
        System.out.printf("长整数3和长整数4%s相等(使用isNotEqualTo方法)%n",hi3.isNotEqualTo(hi4)?"不":"");
        System.out.printf("长整数3%s长整数4(使用isGreaterThan方法)%n",hi3.isGreaterThan(hi4)?"大于":"小于");
        System.out.printf("长整数3%s长整数4(使用isLessThan方法) %n",hi3.isLessThan(hi4)?"小于":"大于");
        System.out.printf("长整数3%s长整数4(使用isGreaterThanOrEqualTo方法)%n",
                hi3.isGreaterThanOrEqualTo(hi4)?"大于等于":"小于");
        System.out.printf("长整数3%s长整数4(使用isLessThanOrEqualTo方法)%n",
                hi3.isLessThanOrEqualTo(hi4)?"小于等于":"大于");
        System.out.printf("长整数3和长整数4的和为:%n");
        hi3.add(hi4);
        hi3.output();
        hi3 = HugeInteger.parse("3456789012345678901234567890123456789012");
        System.out.printf("长整数3和长整数4的差为:%n");
        hi3.substract(hi4);
        hi3.output();
        
    	hi3 = HugeInteger.parse("2345678901234567890123456789012345678901");
    	hi4 = HugeInteger.parse("2345678901234567890123456789012345678901");
        System.out.printf("%n长整数3:%s%n",hi3);
        System.out.printf("长整数4:%s%n",hi4);
        System.out.printf("长整数3和长整数4%s相等(使用isEqualTo方法)%n",hi3.isEqualTo(hi4)?"":"不");
        System.out.printf("长整数3和长整数4%s相等(使用isNotEqualTo方法)%n",hi3.isNotEqualTo(hi4)?"不":"");
        System.out.printf("长整数3%s长整数4(使用isGreaterThan方法)%n",hi3.isGreaterThan(hi4)?"大于":"小于等于");
        System.out.printf("长整数3%s长整数4(使用isLessThan方法) %n",hi3.isLessThan(hi4)?"小于":"大于等于");
        System.out.printf("长整数3%s长整数4(使用isGreaterThanOrEqualTo方法)%n",
                hi3.isGreaterThanOrEqualTo(hi4)?"大于等于":"小于");
        System.out.printf("长整数3%s长整数4(使用isLessThanOrEqualTo方法)%n",
                hi3.isLessThanOrEqualTo(hi4)?"小于等于":"大于");
        System.out.printf("长整数3和长整数4的和为:%n",HugeInteger.add(hi3, hi4));
//        hi3.add(hi4);
//        hi3.output();
//        hi3 = HugeInteger.parse("2345678901234567890123456789012345678901");
        System.out.printf("%n长整数3:%s%n",hi3);
        System.out.printf("长整数3和长整数4的和为:%s%n",HugeInteger.add(hi3, hi4));
        hi3 = HugeInteger.parse("2345678901234567890123456789012345678901");
        System.out.printf("长整数3和长整数4的差为:%n");
        hi3.substract(hi4);
        hi3.output();
        System.out.printf("长整数3%s零%n",hi3.isZero()?"等于":"不等于");

    }
    
}

 

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值