最直接的方式是用 std::to_string 转字符串后取首字符;需处理负数符号和零,性能可接受;循环除法适合无stl环境;log10法易出错,慎用。

用 std::to_string 转字符串再取首字符最直接
对正整数来说,转成字符串后取 [0] 是最不容易出错的方式。它不依赖数学运算、不处理负号逻辑、不纠结位数边界,连 INT_MIN 这种负数也能先取绝对值再安全处理。
- 注意
std::to_string对负数会生成带'-'的字符串,所以得先判断符号或用std::abs - 零要单独处理,
std::to_string(0)返回"0",首字符就是'0' - 性能上比纯数学法略慢,但对绝大多数场景可忽略——除非你在循环里每秒调十万次
示例:
int getFirstDigit(int n) {
if (n == 0) return 0;
std::string s = std::to_string(std::abs(n));
return s[0] - '0';
}
用循环除法提取首位数字(不转字符串)
本质是不断把数字“右移”到个位,适合嵌入式或禁用 STL 的环境。核心逻辑是:只要 n >= 10,就 n /= 10,直到剩一位数。
- 必须用
std::abs(n)处理负数,否则-123 / 10得-12,最后结果是-1,不是想要的1 -
INT_MIN不能直接取std::abs(会溢出),得先转成long long或用条件判断绕过 - 对
0要提前返回,否则循环进不去,结果还是0(其实没问题),但逻辑不显式
示例:
int getFirstDigit(int n) {
if (n == 0) return 0;
long long x = std::abs(static_cast<long long>(n));
while (x >= 10) x /= 10;
return static_cast<int>(x);
}
用 log10 + 幂运算求首位(数学派,慎用)
原理是:若 n 有 d 位,则 10^(d-1) ,所以 <code>n / 10^(d-1) 就是首位。而 d = floor(log10(n)) + 1。
-
std::log10对整数有浮点误差,比如log10(999)可能算出2.999999999,floor后变2,导致除以100得9(正确),但log10(1000)若算成3.000000001,floor还是3,除以1000得1(也对);真正危险的是中间值,比如999999999可能因精度丢一位 - 不支持
0和负数,log10(0)是未定义,log10(-x)报错 - 需要
#include <cmath></cmath>,且链接-lm(某些嵌入式环境不友好)
遇到 INT_MIN 时最容易踩的坑
INT_MIN 是 -2147483648,在 32 位 int 中,它的绝对值无法用 int 表示——std::abs(INT_MIN) 行为未定义(通常回绕成自身)。所有依赖 std::abs 的方法在这里都会失效。
立即学习“C++免费学习笔记(深入)”;
- 最稳妥是先转成更大类型:用
long long接收输入,再做后续操作 - 或者避开
abs:对负数,用n > -10 ? -n : ...分支处理,但代码变啰嗦 - 别信“我只处理正数”——用户传
INT_MIN不需要理由,C++ 不拦着
事情说清了就结束










