十六进制与十进制对照
十六进制 | 十进制 |
0 | 0 |
1 | 1 |
2 | 2 |
3 | 3 |
4 | 4 |
5 | 5 |
6 | 6 |
7 | 7 |
8 | 8 |
9 | 9 |
A | 10 |
B | 11 |
C | 12 |
D | 13 |
E | 14 |
F | 15 |
十六进制与十进制区别
十六进制是满16进1,十进制是满10进1,这里要注意下区别,16进制的字符里面为什么是0-9没有10,这里面进了一位,表示16了。
十六进制转十进制的算法逻辑
处理转换过程分为正序和逆序
正序
从左到右加权累加,每次往右加一个数的时候,原来的数字需要向左变高位移动一位,就是乘以16。比如有一个“1A3”,result记录十进制累加值初始为0,
我们遍历第一次,是1进来:
result=result*16+1=0*16+1=1
第二次,A进来==10,1左移一位:
result=result*16+10=1*16+10=26
第三次,3进来,1A左移一位:
result=result*16+3=26*16+3=419
整体公式其实就是:
result=1*16^2+A*16^1+3*16^0
实现
int hexToDecimalManual(const std::string& hexStr) {
int result = 0;
size_t startIdx = (hexStr.substr(0, 2) == "0x" || hexStr.substr(0, 2) == "0X") ? 2 : 0;
for (size_t i = startIdx; i < hexStr.size(); ++i) {
char c = hexStr[i];
int value;
if (isdigit(c)) {
value = c - '0';
} else if (c >= 'A' && c <= 'F') {
value = 10 + c - 'A';
} else if (c >= 'a' && c <= 'f') {
value = 10 + c - 'a';
} else {
break; // 非法字符终止转换
}
result = result * 16 + value; // 逆序权值累加
}
return result;
}
逆序
逆序是从右到左遍历字符串,有一个base记录处理的权值,每次引入的字符都是更高位的字符,需要做一个权值处理,实现起来和正序差不多,注意方向就行
实现
long long hexToDecimal_Reverse(const string& hex) {
long long result = 0;
long long base = 1; // 初始权值为16^0=1
for (int i = hex.length() - 1; i >= 0; i--) {
char c = hex[i];
int val;
if (c >= '0' && c <= '9') {
val = c - '0';
} else if (c >= 'A' && c <= 'F') {
val = 10 + c - 'A';
} else if (c >= 'a' && c <= 'f') {
val = 10 + c - 'a';
} else {
throw invalid_argument("非法十六进制字符");
}
// 动态调整权值
result += val * base;
base *= 16; // 权值左移(如1→16→256)
}
return result;
}
// 示例输入:hex = "1A3" → 输出419
不建议使用math库的pow,复杂度高了