阿姆斯特朗数是指一个n位正整数,其各位数字的n次幂之和等于它本身;指数必须是原数位数而非固定值,如153(3位)和9474(4位)均为阿姆斯特朗数。

什么是阿姆斯特朗数,以及为什么不能只看位数
阿姆斯特朗数(Armstrong number),也叫自恋数、水仙花数,是指一个 n 位正整数,其各位数字的 n 次幂之和等于它本身。比如 153 是 3 位数,而 1^3 + 5^3 + 3^3 == 153,所以它是阿姆斯特朗数。
关键点在于:**指数必须是原数的位数,不是固定 3**。很多人误以为只判断三位数(水仙花数),但 9474(4 位)满足 9^4 + 4^4 + 7^4 + 4^4 == 9474,也是阿姆斯特朗数。C++ 中没有内置位数或幂运算函数,得自己处理,否则容易漏判或误判。
用 to_string 获取位数并逐位计算幂和
最直观可靠的方式是把整数转成字符串,用 str.length() 得到位数 n,再遍历每个字符转回数字,调用 pow 或手写整数幂(推荐手写,避免 pow 的浮点误差)。
常见错误:pow(9, 4) 返回 6560.999999,强制转 int 变成 6560,导致判断失败。
- 用
std::to_string(x)安全获取位数和各位数字 - 手写幂函数,如
int ipow(int base, int exp),只处理非负整数,循环累乘 - 注意溢出:比如
int最大值约 2e9,9^10已超 3e9,所以输入建议限制在int范围内且位数 ≤ 9(9^9 = 387,420,489,9 个相加也不超 4e9)
int ipow(int base, int exp) {
int res = 1;
while (exp--) res *= base;
return res;
}
<p>bool isArmstrong(int n) {
if (n n) break; // 提前退出防溢出
}
return sum == n;
}</p>
不用字符串:用循环取位 + log10 算位数的风险
有人倾向用 floor(log10(n)) + 1 算位数,再用 n % 10 和 n / 10 取各位。这方法快,但有坑:
-
log10(1000)在某些平台可能返回2.9999999,floor后变 2,位数错判为 3 -
n == 0时log10(0)未定义,直接崩溃 - 负数、零需单独处理,逻辑分散
除非对性能极端敏感且能严格控制输入范围(如只处理 100–999),否则不推荐。字符串法虽稍慢,但语义清晰、边界安全。
测试时容易忽略的边界情况
光测 153、371 不够。这些 case 必须覆盖:
-
0:是 1 位数,0^1 == 0→ 应返回true -
1到9:所有单位数都是阿姆斯特朗数(d^1 == d) -
10:2 位数,1^2 + 0^2 == 1 ≠ 10→false -
9474、54748(5 位)、92727(5 位)等已知多位解 - 接近
INT_MAX的数(如1999999999),验证溢出防护是否生效
实际项目中,如果只是做算法题,用字符串法最稳;如果嵌入式环境禁用 STL,则必须手写取位循环 + 安全位数统计,且务必加 n == 0 分支。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











