数字转换为十六进制数
给定一个整数,编写一个算法将这个数转换为十六进制数。对于负整数,我们通常使用 补码运算 方法。
注意:
- 十六进制中所有字母(a-f)都必须是小写。
- 十六进制字符串中不能包含多余的前导零。如果要转化的数为0,那么以单个字符'0'来表示;对于其他情况,十六进制字符串中的第一个字符将不会是0字符。
- 给定的数确保在32位有符号整数范围内。
- 不能使用任何由库提供的将数字直接转换或格式化为十六进制的方法。
示例1
输入:
26
输出:
"1a"
示例2
输入:
-1
输出:
"ffffffff"
本人的渣渣垃圾代码(Java)
public class ToHex {
public static String toHex(int num) {
if (num >= 0) {
return parse(num);
}else {
return parse((long)Math.pow(2, 32) + num);
}
}
private static String parse(long num){
char c = '0';
StringBuilder s = new StringBuilder();
while (num / 16 > 0) {
c = numToChar(num);
s.append(c);
num = num / 16;
}
s.append(numToChar(num));
return s.reverse().toString();
}
private static char numToChar(long num){
char c = '0';
if (num % 16 <= 9) {
//利用ASCII码
c = (char) (c + num % 16);
}else {
// 'a'的ASCII码为97,对应16进制中的10,所以97 + n - 10为对应的字符的ASCII码
c = (char) (87 + num % 16);
}
return c;
}
public static void main(String[] args) {
String s = toHex(-1);
}
}
- 数字与字符转换可以通过
ASCII码
进行转换。数字0对应的ASCII码值为48,字母A对应的ASCII码为65,字母a对应的ASCII码为97。 - 在32位有符号整数下,
0xffffffff
对应的原码与-1
的补码相同,所以使用(long)Math.pow(2, 32) + num
来代替负数的补码。 - 查看题解,本题主要考察
位运算
,对位运算还缺乏理解,还需要深入学习。
优秀位运算题解:
class Solution {
public String toHex(int num) {
char[] hex = "0123456789abcdef".toCharArray();
StringBuilder str=new StringBuilder();
while(num != 0){
int end = num&15;//比较二进制的差异
//// System.out.println(end);
str.append(hex[end]);
//无符号右移4位
num >>>=4;
}
if(str.length() == 0){
str.append("0");
}
//反转字符
StringBuilder str0=str.reverse();
return str0.toString();
}
}
作者:zhu-five
链接:https://leetcode-cn.com/problems/convert-a-number-to-hexadecimal/solution/zi-fu-huan-chong-qu-jia-su-an-wei-bi-jiao-by-zhu-f/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
对数字的每四位与15(即2进制中的1111or16进制中的f)进行与运算,得出的结果就是这一位的值。最后的推出条件位num = 0,即为0000时退出,数字转换完成。
以下为java源码中IntegerToHexString()方法:
/**
* Returns a string representation of the integer argument as an
* unsigned integer in base 16.
*
* <p>The unsigned integer value is the argument plus 2<sup>32</sup>
* if the argument is negative; otherwise, it is equal to the
* argument. This value is converted to a string of ASCII digits
* in hexadecimal (base 16) with no extra leading
* {@code 0}s.
*
* <p>The value of the argument can be recovered from the returned
* string {@code s} by calling {@link
* Integer#parseUnsignedInt(String, int)
* Integer.parseUnsignedInt(s, 16)}.
*
* <p>If the unsigned magnitude is zero, it is represented by a
* single zero character {@code '0'} ({@code '\u005Cu0030'});
* otherwise, the first character of the representation of the
* unsigned magnitude will not be the zero character. The
* following characters are used as hexadecimal digits:
*
* <blockquote>
* {@code 0123456789abcdef}
* </blockquote>
*
* These are the characters {@code '\u005Cu0030'} through
* {@code '\u005Cu0039'} and {@code '\u005Cu0061'} through
* {@code '\u005Cu0066'}. If uppercase letters are
* desired, the {@link java.lang.String#toUpperCase()} method may
* be called on the result:
*
* <blockquote>
* {@code Integer.toHexString(n).toUpperCase()}
* </blockquote>
* @param i an integer to be converted to a string.
* @return the string representation of the unsigned integer value
* represented by the argument in hexadecimal (base 16).
* @see #parseUnsignedInt(String, int)
* @see #toUnsignedString(int, int)
* @since JDK1.0.2
*/
public static String toHexString(int i) {
return toUnsignedString0(i, 4);
}
/**
* Convert the integer to an unsigned number.
*/
private static String toUnsignedString0(int val, int shift) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
char[] buf = new char[chars];
formatUnsignedInt(val, shift, buf, 0, chars);
// Use special constructor which takes over "buf".
return new String(buf, true);
}
java源代码中也基本是这种思想。我们需要从源码中学习的还有很多。