给你一个十六进制字符串,将其转成十进制并打印(正数)
eg.
hex=“ABF983242F767558F”
dec=“198273280657999746447”
eg.
hex=“32”
dec=“50”
其实也还好,对第二个用例模拟一下可以清晰很多。
简单说一下思路:
- hex 是用来存储 16 进制字符串(0 下标是高位数据)
- dec 是用来存储 10 进制结果字符 (0 下标是高位数据)
假设测试用例是 hex = "3"
,那么这时候 dec
很快就可以看出来是 dec = "3"
对吧。
那么如果 hex = "32"
,那么这里的 "3"
其实是 16 进制里面的 十位,所以我们就需要将他 16 * 3 = 48
。但是这显然还不是 10 进制的结果,因为还有一个 16 进制的 2 没有处理。我们需要将这个 2 和上面的结果相加。再重新调整 10 进制每一位的结果。最终 dec = "50"
但是,如果这时候你又发现 hex = "329"
呢,你会发现这个 十进制 dec
的原来的每一位都要 * 16,并且还需要重新加上十六进制中的那个新的 个位数 9
,而加上这个 9
又可能会导致 dec
的某个下标的进位。
然后这里是我的代码和测试用例,可以参考一下:
int hex2dec(char hex) {
char h = tolower(hex);
if (h >= 'a' && h <= 'z') {
return h - 'a' + 10;
}
else if (h >= '0' && h <= '9') {
return h - '0';
}
return -1;
}
std::string LargeNumberHex2Dec(const std::string& hex) {
std::string dec("0");
// 从高位开始遍历
for (int i = 0; i < hex.size(); i++) {
for_each(dec.begin(), dec.end(), [](char& ch) { ch -= '0'; }); // 全部转成数字, 方便计算
int d = hex2dec(hex[i]); // 将该字符转成 10 进制数字
int carry = d; // 这里可以理解为把 carry(进位) 初始化为 该个位数
// 因为每次 for 循环中,dec 会新增一个 新的个位(可以尝试这么理解)
// 开始更新十进制
for (int j = dec.size() - 1; j >= 0; j--) {
int cur = dec[j] * 16 + carry; // 每一位都要扩大 16 倍,然后向高位进位
dec[j] = cur % 10;
carry = cur / 10; // 进位
if (carry && j == 0) { // 这里举个例子,比如 dec = "11", 但是 carry = 2, 那么结果就会是 "211"
dec.insert(dec.begin(), 0); // 插入 0 是方便再次进入该循环计算
j ++;
}
}
for_each(dec.begin(), dec.end(), [](char& ch) { ch += '0'; }); // 全部转回字符
}
return dec;
}
测试用例
int main() {
const char* hex = "32";
if (LargeNumberHex2Dec(hex) != "50") {
std::cout << "hex = 32 fail" << std::endl;
}
hex = "FFFF";
if (LargeNumberHex2Dec(hex) != "65535") {
std::cout << "hex = FFFF fail" << std::endl;
}
hex = "FFFF999996663633";
if (LargeNumberHex2Dec(hex) != "18446631483665167923") {
std::cout << "hex = FFFF999996663633 fail" << std::endl;
}
hex = "A1B2C3D4E5F6";
if (LargeNumberHex2Dec(hex) != "177789161760246") {
std::cout << "hex = A1B2C3D4E5F6 fail" << std::endl;
}
hex = "ABF983242F767558F";
if (LargeNumberHex2Dec(hex) != "198273280657999746447") {
std::cout << "hex = ABF983242F767558F fail" << std::endl;
}
}