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
测试结果:
长整数3:3456789012345678901234567890123456789012 长整数4:2345678901234567890123456789012345678901 长整数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
长整数3:2345678901234567890123456789012345678901 长整数4:2345678901234567890123456789012345678901 长整数3和长整数4相等(使用isEqualTo方法) 长整数3和长整数4相等(使用isNotEqualTo方法) 长整数3小于等于长整数4(使用isGreaterThan方法) 长整数3大于等于长整数4(使用isLessThan方法) 长整数3大于等于长整数4(使用isGreaterThanOrEqualTo方法) 长整数3小于等于长整数4(使用isLessThanOrEqualTo方法) 长整数3和长整数4的和为:
长整数3:2345678901234567890123456789012345678901 长整数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()?"等于":"不等于");
}
}