网站首页 > java教程 正文
你有没有过这种崩溃:用Java算“12345678901234567890 + 98765432109876543210”,结果跳出个“9223372036854775807”(long类型最大值),活生生算错了?其实Java不是算不了大数,只是你没找对方法——用字符串当“草稿纸”,模拟小时候列竖式加法,就算是“100位的天文数字”也能加得明明白白,比计算器还靠谱!今天用“算工资总和”的段子给你讲透,看完笑到会写代码,再也不怕“数字太大算崩了”~
先懂“大数难题”: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大数相减”——比相加多一步“借位”,但照样用字符串当草稿纸,轻松搞定!
- 上一篇: Java:有哪些快速学习Java语言的技巧?
- 下一篇: 零基础可以学编程,如果你信,你会掉进深渊。
猜你喜欢
- 2025-09-21 工控必备:5个免费的PLC通讯检测工具!
- 2025-09-21 零基础可以学编程,如果你信,你会掉进深渊。
- 2025-09-21 使用ANTLR开发自己的DSL语言(一)_antlr llvm
- 2025-09-21 Java:有哪些快速学习Java语言的技巧?
- 2025-09-21 由ArcMap属性字段自增引出字段计算器使用Python的技巧
- 2025-09-21 制作简易页面计算器的详细教程和代码分享
- 2025-09-21 JAVA自己写什么功能可以提升技术?
- 2025-09-21 java swing 开发简单计算器代码_利用java swing编写一个计算器界面
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)