阿姆斯特朗数判定逻辑是:一个n位非负整数,其各位数字的n次幂之和等于该数本身;需先求位数n(0特判为1位),再对每位数字用整数幂累加,全程使用long long防溢出并避免浮点运算。

什么是阿姆斯特朗数(判定逻辑本身)
阿姆斯特朗数(也叫自恋数、水仙花数)的判定逻辑非常明确:一个 n 位正整数,其各位数字的 n 次幂之和等于它本身。例如 153 是 3 位数,而 1^3 + 5^3 + 3^3 == 153,所以它是阿姆斯特朗数。
注意:0 和 1 是特例,它们都是 1 位数,且 0^1 == 0、1^1 == 1,因此都算。但负数直接排除——阿姆斯特朗数定义只针对非负整数。
关键点不是“怎么写循环”,而是「位数」和「幂次」必须严格对应。很多人误用固定指数(比如总按 3 次方算),结果把 9474(4 位,9^4+4^4+7^4+4^4 == 9474)漏掉或错判。
如何安全获取整数位数并避免 int 溢出
用 to_string(x).length() 最直观,但要注意 x == 0 时得单独处理(否则 to_string(0) 是 "0",长度为 1,没问题);更稳妥的是用循环除法,但必须先取绝对值再算位数——因为负数不能直接参与位数统计,且后续幂运算只对各位数字(非负)进行。
更大的坑在幂运算:C++ 标准库没有整数幂函数,pow(9, 10) 返回 double,可能因精度丢失导致 9^10 == 3486784400 被算成 3486784401,最终判定失败。务必手写整数幂或用 long long 累乘,并在每次乘法前检查是否溢出。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 用
abs(x)得到非负副本用于位数统计和拆位 - 位数
n一旦确定,所有幂运算都基于这个n,不是硬编码 - 累加幂和时用
long long类型,防止int溢出(如 9 位数最大可能和约 3.87e9,超过INT_MAX)
完整判定函数示例(含边界处理)
下面是一个鲁棒的 C++ 实现,覆盖 0、个位数、大数(如 9474、54748):
bool isArmstrong(int x) {
if (x 0) { n++; t /= 10; }
if (x == 0) n = 1; // 0 是 1 位数
long long sum = 0;
t = x;
while (t > 0) {
int digit = t % 10;
long long power = 1;
for (int i = 0; i INT_MAX && sum + power > INT_MAX) break; // 提前防溢出
}
sum += power;
t /= 10;
}
return sum == orig;
}
这个版本不依赖 <cmath></cmath>,避免 pow 的浮点误差;用 long long 承载中间和;显式处理 0;循环中每步都检查溢出可能。测试 isArmstrong(0)、isArmstrong(9474)、isArmstrong(-153) 都符合预期。
为什么不能用 std::pow 或字符串转 double 再比较
std::pow(9, 10) 在多数平台上返回 double,而 double 对整数 > 2^53 无法精确表示。即使你只处理 10 位以内数,pow(9, 10) 的二进制近似值可能差 1,导致和比较失败。字符串方式(如把每位转 string 再用 stoll 做幂)看似绕过浮点,但 stoll 调用底层仍可能引入转换开销和潜在异常,且没解决幂运算本身的整数性问题。
真正干净的做法是:位数确定后,用整数循环乘法计算幂;所有中间值用足够宽的整型(long long);输入范围限定在 int,就无需支持任意精度库。
最容易被忽略的是:阿姆斯特朗数判定本质是「位数敏感」的整数运算,任何引入浮点、字符串解析或隐式类型转换的路径,都在悄悄增加不可控误差源。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










