专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java算不了超大数?用字符串当“草稿纸”,再大的数也能加!

temp10 2025-09-21 22:27:11 java教程 1 ℃ 0 评论

你有没有过这种崩溃:用Java算“12345678901234567890 + 98765432109876543210”,结果跳出个“9223372036854775807”(long类型最大值),活生生算错了?其实Java不是算不了大数,只是你没找对方法——用字符串当“草稿纸”,模拟小时候列竖式加法,就算是“100位的天文数字”也能加得明明白白,比计算器还靠谱!今天用“算工资总和”的段子给你讲透,看完笑到会写代码,再也不怕“数字太大算崩了”~

先懂“大数难题”:Java的“小口袋”装不下“大西瓜”

Java算不了超大数?用字符串当“草稿纸”,再大的数也能加!

Java里的数字类型(int、long)就像“小口袋”:int最多装10位数字,long最多装19位,要是超过这个数,就像把大西瓜硬塞进小口袋,要么挤破(溢出),要么变成乱码(结果错误)。

比如你是财务,要算“10个月工资总和”,每个月工资是“1234567890123456789”(18位),10个月加起来是“12345678901234567890”(19位),用long类型算,结果直接变成“-6108406672557752826”(负数,溢出了),老板看了都得怀疑你算错账!

这时候,字符串就成了“超大草稿纸”——不管数字有多少位,都能像写作文一样写在字符串里,再模拟小时候列竖式的方法逐位相加,就算是1000位的“天文数字”,也能加得清清楚楚~

核心思路:像小时候列竖式,字符串上“掰手指”算加法

大数相加的本质,就是用字符串模拟手工列竖式:

1. 把两个大数像竖式一样“右对齐”(从最后一位,也就是个位开始加);

2. 逐位相加,遇到超过10的就“进位”(比如8+5=13,本位写3,进位1);

3. 把相加的结果倒着记下来(因为从个位开始算,先算的是结果的最后一位);

4. 要是最后还有进位(比如999+1=1000,最后进位1),记得把进位加上;

5. 把倒着的结果再倒过来,就是最终答案。

用“工资相加”举例:算“123(月工资)+ 4567(年终奖)”,竖式是:

123
+4567
------
4690

用字符串算,就是先对齐个位(3和7),再算十位(2和6),再算百位(1和5),最后算千位(0和4),过程一模一样,只不过把“草稿纸”换成了字符串~

Java实现5步走:竖式加法类比+代码,新手一看就懂

Java实现大数相加,分“对齐位数→逐位相加→处理进位→倒序存结果→补进位”5步,每一步都对应列竖式的操作,代码像“写竖式笔记”一样简单:

第一步:准备“草稿纸”和“工具”——初始化指针和变量

先给两个字符串(大数)分别设一个“指针”(i和j),从最后一位(个位)开始;再准备一个“进位变量”(carry),记录每次相加要进位的数;最后用一个StringBuilder当“临时草稿本”,记录逐位相加的结果(倒着记)。

代码初始化:

public class BigNumberAdd {
          public static String addBigNumbers(String num1, String num2) {
                  // 指针:从两个数的最后一位(个位)开始
                  int i = num1.length() - 1;
                  int j = num2.length() - 1;
                  int carry = 0; // 进位:比如8+5=13,carry=1
                  StringBuilder result = new StringBuilder(); // 临时草稿本(倒序存结果)
                  // 后面步骤写这里...
          }
}

第二步:逐位“掰手指”相加——从个位加到最高位

让两个指针从个位开始,一步步往左移(往高位加),每次取两个指针指向的数字相加,再加上进位,算出自位结果和新的进位。如果某个数先加完(指针移到最前面),就用0代替(比如123+4567,123的千位是0)。

代码实现:

public static String addBigNumbers(String num1, String num2) {
              int i = num1.length() - 1;
              int j = num2.length() - 1;
              int carry = 0;
              StringBuilder result = new StringBuilder();
              // 只要有一个数没加完,或还有进位,就继续加
              while (i >= 0 || j >= 0 || carry > 0) {
                        // 取当前位的数字,没数字了就用0代替
                        int digit1 = (i >= 0) ? (num1.charAt(i) - '0') : 0;
                        int digit2 = (j >= 0) ? (num2.charAt(j) - '0') : 0;
                        // 计算当前位总和: digit1 + digit2 + 进位
                        int sum = digit1 + digit2 + carry;
                        // 本位结果:sum%10(比如13%10=3)
                        int currentDigit = sum % 10;
                        // 新的进位:sum/10(比如13/10=1)
                        carry = sum / 10;
                        // 把本位结果写到草稿本(倒序存,后面再反转)
                        result.append(currentDigit);
                        // 指针往左移一位(往高位走)
                        i--;
                        j--;
              }
              // 后面处理结果...
}

比如算“123+4567”:

- 第一次:i=2(3),j=3(7),sum=3+7+0=10,本位0,进位1,草稿本存“0”;

- 第二次:i=1(2),j=2(6),sum=2+6+1=9,本位9,进位0,草稿本存“09”;

- 第三次:i=0(1),j=1(5),sum=1+5+0=6,本位6,进位0,草稿本存“096”;

- 第四次:i=-1(0),j=0(4),sum=0+4+0=4,本位4,进位0,草稿本存“0964”;

第三步:“倒过来”得结果——把草稿本的内容反转

因为草稿本是从个位开始存的(先存0,再存9,再存6,最后存4),所以结果是“0964”,需要反转一下变成“4690”,才是正确答案。

代码收尾:

// 反转草稿本,得到最终结果
return result.reverse().toString();
}
        // 测试:算123 + 4567 = 4690
        public static void main(String[] args) {
        System.out.println(addBigNumbers("123", "4567")); // 输出4690
        // 再测个大数:12345678901234567890 + 98765432109876543210 = 111111111011111111100
        System.out.println(addBigNumbers("12345678901234567890", "98765432109876543210"));
}

运行结果完美,就算是20位的超大数,也能精准算出结果,再也不怕溢出了!

避坑提醒:新手常踩的3个“竖式加法坑”

1. 从字符串开头开始加,搞反顺序:比如算“123+4567”,从“1”和“4”开始加(千位和千位),结果变成“5790”(错的),就像小时候列竖式把数字左对齐,老师得打个叉。记住:必须从最后一位(个位)开始加,右对齐才是正确的竖式!

2. 加完忘了处理最后进位:比如算“999+1”,逐位相加后carry=1,但没把进位加到结果里,最后得到“000”(反转后还是“000”),实际应该是“1000”。就像小时候算加法,最后忘写进位的1,被妈妈骂“粗心鬼”——循环条件必须加上“carry>0”,确保最后进位也能加上!

3. 直接用char做加法,得到乱码:比如把`num1.charAt(i)`直接当数字加,结果是ASCII码相加('3'的ASCII是51,'7'是55,51+55=106,对应字符'j'),纯属瞎算。记住:char转数字要减'0'('3'-'0'=3),就像把草稿纸上的数字“念”出来再算~


互动时间:来测测你的“大数加法力”!

1. 用今天的代码算“9999999999 + 1”,结果是啥?(提示:逐位相加后carry=1,最后补进位,结果是“10000000000”)

2. 要是输入的两个大数是“0”和“0”,代码会返回啥?(提示:sum=0+0+0=0,结果是“0”,正确处理边界)

3. 你小时候算加法有没有过“忘进位”“对错位”的糗事?比如把“12+34”算成“45”(应该是46),评论区说说你的“数学小插曲”!

评论区交出你的答案,前3名答对的送“Java大数运算手册”(含大数加减乘除的通俗讲解+代码模板)!关注我,下期揭秘“Java大数相减”——比相加多一步“借位”,但照样用字符串当草稿纸,轻松搞定!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表