阿姆斯特朗数是指一个n位正整数,其各位数字的n次幂之和等于它本身;需用整数幂函数、实际位数统计、long long防溢出,且排除负数和0。

什么是阿姆斯特朗数?先确认判断逻辑
阿姆斯特朗数(也叫自恋数、水仙花数)是指一个 n 位正整数,其各位数字的 n 次幂之和等于它本身。比如 153 是 3 位数,而 1^3 + 5^3 + 3^3 == 153,所以它是阿姆斯特朗数。
注意:负数、0 不算(严格定义中只考虑正整数),且位数 n 必须是该数实际的十进制位数,不能硬编码为 3 或 4。
常见错误是直接用 pow(10, n) 算位数,或用浮点 pow() 计算整数幂导致精度丢失——pow(5, 3) 返回的可能是 124.999999,转整后变 124。
如何安全提取每位数字并计算 n 次幂
别依赖 <cmath></cmath> 的 pow() 处理整数幂。自己写个整数幂函数更稳,尤其当 n 较小(通常 ≤ 10,因为 10^10 已超 int 范围)。
- 用循环累乘实现
ipow(int base, int exp),避免浮点误差 - 用
while (n) { digits.push_back(n % 10); n /= 10; }提取各位,同时计数得位数len - 注意:原数要提前保存,因为除法会破坏它
- 对于
0单独处理(虽然按定义不算,但代码健壮性需覆盖)
C++ 实现示例(含边界处理)
#include <iostream>
#include <vector>
#include <cmath> // 仅用于 abs(),非 pow()
<p>int ipow(int base, int exp) {
int res = 1;
while (exp-- > 0) res *= base;
return res;
}</p>
<p>bool isArmstrong(int n) {
if (n digits;
int len = 0;
while (n) {
digits.push_back(n % 10);
n /= 10;
len++;
}
long long sum = 0; // 防止中间结果溢出,如 9999999 的 7 次幂
for (int d : digits) {
sum += ipow(d, len);
if (sum > orig) break; // 提前退出优化
}
return sum == orig;
}</p></cmath></vector></iostream>
关键点:sum 用 long long,因为 9^10 ≈ 3.5e9,已超 int;ipow 不调用 std::pow;len 由实际位数决定,不是写死的。
容易被忽略的坑:大数与符号处理
标准 int 最大支持到约 2e9,而 10 位阿姆斯特朗数最大可能是 9^10 * 10 ≈ 3.5e10,远超范围。所以:
- 输入若为
long long,需重写位数统计(to_string(x).size()更稳妥,但注意负号) -
isArmstrong(-153)必须返回false,不能因取模行为误判 - 某些资料把
0算作 1 位阿姆斯特朗数(0^1 == 0),但主流定义排除 0 —— 看清题目要求 - 用
std::to_string(n).length()获取位数虽简洁,但对负数会多算一位,需先取绝对值
真正麻烦的不是算法,而是位数统计方式、幂运算精度、中间值溢出这三处细节。写完务必用 0、1、99、9474、9926315 这类典型值测一遍。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











