
charAt() 返回的是字符的 Unicode 码点(如 '0' 对应 48),而非字符表示的数字本身;直接赋值给 int 会导致误将 ASCII 值当作数值使用,需显式转换为对应数字。
`charat()` 返回的是字符的 unicode 码点(如 `'0'` 对应 48),而非字符表示的数字本身;直接赋值给 `int` 会导致误将 ascii 值当作数值使用,需显式转换为对应数字。
在实现阿姆斯特朗数(Armstrong number)判断逻辑时,一个常见误区是误用 String.charAt(int) 方法。例如,在如下代码中:
int base = str.charAt(i); // ❌ 错误:获取的是字符的 ASCII 值
当 str = "30" 且 i = 0 时,str.charAt(0) 返回字符 '3',其 Unicode 码点为 51(即 '0' = 48, '1' = 49, ..., '3' = 51)。因此 base 被赋值为 51,而非预期的数字 3——这将导致后续 Math.pow(base, len) 计算严重偏离。
✅ 正确做法是将字符安全地转换为对应的数字整型值。推荐以下三种方式(按健壮性与性能排序):
1. 使用字符减法(最高效,适用于纯数字字符串)
int digit = str.charAt(i) - '0'; // ✅ 安全、快速、无异常
原理:'0' 到 '9' 在 Unicode 中连续排列,'3' - '0' == 51 - 48 == 3。
2. 使用 Character.getNumericValue()(语义清晰,支持多进制)
int digit = Character.getNumericValue(str.charAt(i)); // ✅ 可读性强,自动处理数字字符
该方法能正确解析 '0'–'9'、'a'–'z' 等,对非数字字符返回 -1,建议配合校验:
char c = str.charAt(i);
if (!Character.isDigit(c)) {
throw new IllegalArgumentException("Non-digit character found: " + c);
}
int digit = Character.getNumericValue(c);
3. 使用 Integer.parseInt()(不推荐用于单字符)
int digit = Integer.parseInt(str.substring(i, i + 1)); // ⚠️ 开销大,易抛 NumberFormatException
虽可行,但创建临时字符串对象并触发完整解析流程,性能差且需 try-catch,仅在不确定输入格式时考虑。
? 额外修正原代码问题:
- result=+Math.pow(...) 应为 result += Math.pow(...)(原写法是赋值而非累加);
- Math.pow() 返回 double,而阿姆斯特朗数需精确整数运算,建议改用 long 类型与自定义幂函数,或最后用 (long) Math.round(result) 截断浮点误差;
- 外层循环变量 number 与内层逻辑无实际用途,应聚焦于当前 str 的各位数字处理。
✅ 优化后的核心片段示例:
private static boolean isArmstrong(int n) {
String str = String.valueOf(n);
int len = str.length();
long sum = 0;
for (int i = 0; i <p>总结:charAt() 是获取字符的工具,不是数字提取器。始终明确区分「字符」与「数值」概念,优先采用 c - '0' 进行单数字字符转整型,兼顾性能、可读性与安全性。</p>










