开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第11天,点击查看活动详情
一、题目描述:
给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。
注意:
- 十六进制中所有字母(a-f)都必须是小写。
- 十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符'0'来表示;对于其他情况,十六进制字符串中的第一个字符将不会是0字符。
- 给定的数确保在32位有符号整数范围内。
- 不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。
示例 1:
输入:
26
输出:
"1a"
示例 2:
输入:
-1
输出:
"ffffffff"
二、思路分析:
在计算机中,负整数是用其二进制的补码表示的。故这道题的第一个知识点是负整数补码的计算;第二个知识点是二进制向16进制的转化,下面分别给与叙述:
对于一个负整数,其补码的计算:保持最高位的符号位不变,其余位取反,在加1即可。同样地,还可以用该负数的绝对值与掩码mask做异或运算,再加1,其中mask是无符号型的 unsigned mask = (unsigned)(-1)。-1在计算机内存中是用它的补码表示的,是32个1,是有符号的,这里将其作为掩码,不关心正负,只要各个位上的值,故需要将其转为无符号的。
二进制转化为16进制,每次用数num对16做除法,其余数是18进制表示中的最右边1位,商继续转化即可,用下面的位运算更高效一些。
最后一点,为了防止溢出,可以将所给的32位的num转为64位整型。
三、AC 代码:
class Solution {
public:
string toHex(int num) {
if(num == 0) return "0";
int64_t temp = num;//用int64类型,防止超界
unsigned mask = (unsigned)(-1);//-1在计算机内存中是用它的补码表示的,是32个1,这里为了取num是负数时,num的补码,需要将mask转成无符号型,
if(num < 0 ) temp = (-temp ^ mask) + 1;//求补码,整数的话,补码是其本身,负数的话,符号位不变,其余位取反,再加1;也可以用负数的绝对值与上面的mask做异或,再加1,同样可以得到补码。
char map[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
string res;
while(temp != 0 ) {
res = map[temp&15] + res;
temp >>= 4;
}
return res;
}
};
四、总结:
此题注意下补码问题即可。