如何在Java中添加任意长度的两个数字?

15

如何在Java中添加任意长度的两个数字?

例如,在Java中,long类型大小为64位。所以最大范围是-9223372036854775808到9223372036854775807。我是对的吗?

因此,如果我们想要添加一个比这更大的数字,就像下面这样,我会得到一个错误。

"Integer Number too large"

long a = 9223372036854775807L;
long b= 9223372036854775808L;

在C语言中,我们可以将这些数字作为char数组,并通过遍历每个字符的地址并使用一些数据结构,可以添加任何大小的两个数字。

在Java中该怎么做呢?我们可以通过String中的每个字符地址进行遍历吗?


感谢您的回复。

我已尝试通过将数字作为字符串传递并从末尾添加每个字符来编写代码。它对我很有效。

使用BigInteger和我指定的方法(从末尾添加每个字符并将余数存储在临时变量中等等)添加两个非常大的数字之间是否存在巨大差异? BigInteger的基础机制是否与我的代码相同(从末尾添加每个字符)?

谢谢。


在C语言中,我们也可以使用现有的任意精度整数库,例如GMP(http://gmplib.org/)。 - SingleNegationElimination
8个回答

21
你可以使用一个 BigInteger
BigInteger a = new BigInteger("9223372036854775807");
BigInteger b = new BigInteger("9223372036854775808");
BigInteger result = a.add(b);

BigInteger 可以让你处理任意大小的数字,但是相比于 longint,会损失相当多的性能。


7

BigInteger可以让您使用任意大小的数字,但是与longint相比,性能会大大降低。

实际上,如果您只需要运行此操作一次(用户输入两个数字,然后得到结果),则使用BigInteger是可以的。但是,如果您需要多次执行加法操作,则可以使用自己的大整数实现。当我参加ACM比赛时,我们经常使用基于char数组的自己的实现(在C ++中)。我建议使用以下代码。假设有两个整数数组A和B。A [0]B [0]存储相应数字的长度。 A [i]B [i]存储数字本身。 A [1]B [1]是最低有效位。因此,数字1234将对应于这样一个数组:{4,4,3,2,1}。

现在,假设我们想要将这些数字相加并以相同格式存储在数组C中。这是一个示例代码,您可以使用它:

int len1 = A[0],  len2 = B[0], divisor = 0;
int len = len1 >= len2 ? len1 : len2;
for (int i=1;i<=len;i++) {
  if (i>len1) C[i] = B[i]+divisor;
  else if (i>len2) C[i] = A[i]+divisor;
  else C[i] = A[i]+B[i]+divisor;
  divisor = C[i]/10;
  C[i] %= 10;
}
while (divisor>0) {
  C[++len] = divisor%10;
  divisor /= 10;
}
C[0] = len;

这段代码使用了简单的算术加法规则,应该比 BigInteger 的通用实现工作速度更快。使用它时请尽情享受。


6

使用BigInteger

这里是一个例子。

示例代码(基于上面的链接) -

BigInteger reallyBig1 = new BigInteger("1234567890123456890");
BigInteger reallyBig2 = new BigInteger("2743534343434361234");
reallyBig = reallyBig.add(reallyBig2);

1
为什么数字里面有字母? - jjnguy
@Justin :) 打乱按键尝试创建大数字时出现了笔误。感谢指出。好的观察力!已更正。 - Gopi
也许你的意思是第二行应该是 BigInteger reallyBig2 = new BigInteger("27435dfdsafasd61234",32); - MAK
啊,好的。不确定你是否有意这样做。 - jjnguy

3

不确定为什么我的回答被评为负分,因为提供的链接显然是官方的Java文档,并且该页面上的所有信息足以让Manoj确定如何使用BigInteger。 - Sam Day
当然,这是Java 1.4.2文档,非常老旧。(虽然我没有因此评分降低)(但这也是我不给好评的原因=)) - amara
点赞是因为你提供了相关答案,但1.4.2不太算是“官方”文档,因为它已经很旧了... - pstanton
1
我对这个答案进行了负评,因为你只是发布了一个链接。总的来说,在我看来,SO上的答案应该在提供链接之前提供一些基本信息,以便提问者更好地理解。 - jjnguy
@Sam,欢迎。我讨厌挑剔……这只是一个坏习惯。 - jjnguy
链接已失效。 - Muhd

1
使用BigInteger相加两个非常大的数字和我上面指定的方法(从末尾添加每个字符并将余数存储在临时变量中)之间有什么很大的区别吗?
区别在于您可以使用更大的基数,例如。假设基数为10000,而不仅仅是10。当我的先前答案的代码像这样修改时:
int len1 = A[0],  len2 = B[0], divisor = 0;
int len = len1 >= len2 ? len1 : len2;

for (int i=1;i<=len;i++) {
  if (i>len1) C[i] = B[i]+divisor;
  else if (i>len2) C[i] = A[i]+divisor;
  else C[i] = A[i]+B[i]+divisor;
  divisor = C[i]/10000;
  C[i] %= 10000;
}
while (divisor>0) {
  C[++len] = divisor%10000;
  divisor /= 10000;
}
C[0] = len;

在这种情况下,代码运行速度会快4倍(因为虚拟机在算术运算上没有区别,因为它们仅取决于常量)。此外,这意味着整数数组将变小4倍。唯一的问题是如何格式化输出。

1
创建一个堆栈类,并从用户获取数字作为字符串,将它们转换为字符串并将它们推入堆栈。这里我已经编写了两个大数相加的完整代码,包括堆栈类。只需在命令提示符中键入javac mystack.java,然后键入java mystack即可。
import java.util.*;
public class mystack {
int maxsize=0;
int top=-1;
int array []=new int [0];


public mystack (int size)
{
    maxsize=size;
    array=new int [maxsize];
}

public void push (int x)
{   
    top=top+1;
    array[top]=x;
}

public int pop ()
{
    int elt=array[top];
    top--;
    return elt;

}

public boolean stackisfull()
{
    return(top==maxsize-1);
}

public boolean stackisempty()
{
    return(top==-1);
}

public int peak ()
{
    int peak =array[top];
    return peak;
}

public static void main (String args[]){
Scanner in=new Scanner (System.in);

System.out.println("Enter the 1st number");
String number1 = in.nextLine();
System.out.println();
System.out.println("Enter the 2nd number");
String number2 = in.nextLine();
System.out.println();

String temp="";




 if(number1.length()>number2.length())
 {
    temp=number1;
    number1=number2;
    number2=temp;
 }

    int k=0;


 mystack S1 = new mystack (number1.length());

      for(int i=0;i<number1.length();i++)
       {
            String str=Character.toString(number1.charAt(i));
            S1.push(Integer.parseInt(str));
       } 

 mystack S2 = new mystack (number2.length());

     for(int i=0;i<number2.length();i++)
        {
            String str=Character.toString(number2.charAt(i));
            S2.push(Integer.parseInt(str));
        } 

 mystack S3 =new mystack (number2.length());

 while(!S1.stackisempty())
 {
     int x=S1.pop();
     int y=S2.pop();

     int times=(x+y+k)/10; int remainder =(x+y+k)%10;
     k=0;

     if(times==0)
     {
        S3.push(remainder);
     }

     else
     {
         S3.push(remainder);
         k=1;
     }
 }
    while(!S2.stackisempty())
    {
        if(k==1)
        {
            S3.push(k+S2.pop());
            k=0; 
        }
       else
        S3.push(S2.pop());
    }

    System.out.print("Addition is ");

    while(!S3.stackisempty())
    {
        System.out.print(S3.pop());
    }

}
}

1
public class AddNumbers {
    public static void main(String args[]) {
        String a = new String("3999988889999999995555558888999444333333333222229998877666555444888888");
        String b = new String("56867865876989679765465456412332199");
        int loop1 = 0;
        int loop2 = 0;
        StringBuilder sum = new StringBuilder("");
        int carry = 0;
        for (loop1 = a.length() - 1, loop2 = b.length() - 1; loop1 >= 0 || loop2 >= 0; loop1--, loop2--) {
            int indiv1 = 0;
            if (loop1 >= 0)
                indiv1 = Integer.parseInt("" + a.charAt(loop1));
            int indiv2 = 0;
            if (loop2 >= 0)
                indiv2 = Integer.parseInt("" + b.charAt(loop2));
            int summation = indiv1 + indiv2 + carry;
            double d = Math.floor(summation / 10);
            carry = (int) d;
            int sum2 = summation % 10;
            sum.append(sum2);
        }
        System.out.println(sum.reverse());
    }
}

0
    import java.math.BigInteger;
    import java.util.Scanner;

    public class BigIntergerSumExample {

        public static void main(String args[]) {

            BigInteger number1;
            BigInteger number2;
            BigInteger sum;
            Scanner sc = new Scanner(System.in);
            System.out.println("Enter the value of number 1");
            number1 = sc.nextBigInteger();
            System.out.println("Enter the value of number 2");
            number2 = sc.nextBigInteger();


            BigInteger a = new BigInteger(""+number1);
            BigInteger b = new BigInteger(""+number2);
            BigInteger result = a.add(b);

            System.out.println("Sum is Two numbers : -> " + result);
        }

    }

**OUTPUT IS** 

Enter the value of number 1
1111111111111111111111111111111111111111111111111
Enter the value of number 2
2222222222222222222222222222222222222222222222222
Sum is Two numbers : -> 
3333333333333333333333333333333333333333333333333

import java.math.BigInteger 可以让您处理任意大小的数字,


导入 java.math.BigInteger。 - Keshav Gera

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接