本文主要是介绍Convert a Number to Hexadecimal,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目地址:https://leetcode.com/problems/convert-a-number-to-hexadecimal/
Given an integer, write an algorithm to convert it to hexadecimal. For negative integer, two’s complement method is used.
Note:
- All letters in hexadecimal (a-f) must be in lowercase.
- The hexadecimal string must not contain extra leading 0s. If the number is zero, it is represented by a single zero character ‘0’; otherwise, the first character in the hexadecimal string will not be the zero character.
- The given number is guaranteed to fit within the range of a 32-bit signed integer.
- You must not use any method provided by the library which converts/formats the number to hex directly.
Example 1:
Input:
26Output:
"1a"
Example 2:
Input:
-1Output:
"ffffffff"
题目是将十进制转换为十六进制,整数还是比较好处理的,但是这个题目的关键是负数,要理解负数在计算机中是如何表示的:
public class ConvertANumberToHexadecimal {public static final String[] digit= {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};public String toHex(int num) {StringBuilder reslut = new StringBuilder("");if (num > 0) {while (num != 0) {reslut.insert(0, digit[num % 16]);num /= 16;}} else if (num == 0){reslut.insert(0, "0");} else {// 以下是截取十六进制每位对应的二进制数值// 15 to binnary: 0000 0000 0000 0000 0000 0000 0000 1111reslut.insert(0, digit[num & 15]);// 240 to binnary: 0000 0000 0000 0000 0000 0000 1111 0000reslut.insert(0, digit[(num & 240) >> 4]);// 3840 to binnary: 0000 0000 0000 0000 0000 1111 0000 0000reslut.insert(0, digit[(num & 3840) >> 8]);// 61440 to binnary: 0000 0000 0000 0000 1111 0000 0000 0000reslut.insert(0, digit[(num & 61440) >> 12]);// 983040 to binnary: 0000 0000 0000 1111 0000 0000 0000 0000reslut.insert(0, digit[(num & 983040) >> 16]);// 15728640 to binnary: 0000 0000 1111 0000 0000 0000 0000 0000reslut.insert(0, digit[(num & 15728640) >> 20]);// 251658240 to binnary: 0000 1111 0000 0000 0000 0000 0000 0000reslut.insert(0, digit[(num & 251658240) >> 24]);// 1879048192 to binnary: 0111 0000 0000 0000 0000 0000 0000 0000reslut.insert(0, digit[((num & 1879048192) >> 28) + 8]);}return reslut.toString();}public static void main(String[] args) {ConvertANumberToHexadecimal hexadecimal = new ConvertANumberToHexadecimal();System.out.println(hexadecimal.toHex(-13));}
}
其实在JDK中已经封装好了十进制转十六进制的方法,它是这么写的:
Integer.toHexString(int i)
那么我们看一下JDK是怎么实现的:
/*** 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);
}
然后再看下toUnsignedString0及其内部所涉及到的方法的实现:
/*** 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);
}/*** Returns the number of zero bits preceding the highest-order* ("leftmost") one-bit in the two's complement binary representation* of the specified {@code int} value. Returns 32 if the* specified value has no one-bits in its two's complement representation,* in other words if it is equal to zero.** <p>Note that this method is closely related to the logarithm base 2.* For all positive {@code int} values x:* <ul>* <li>floor(log<sub>2</sub>(x)) = {@code 31 - numberOfLeadingZeros(x)}* <li>ceil(log<sub>2</sub>(x)) = {@code 32 - numberOfLeadingZeros(x - 1)}* </ul>** @param i the value whose number of leading zeros is to be computed* @return the number of zero bits preceding the highest-order* ("leftmost") one-bit in the two's complement binary representation* of the specified {@code int} value, or 32 if the value* is equal to zero.* @since 1.5*/
public static int numberOfLeadingZeros(int i) {// HD, Figure 5-6if (i == 0)return 32;int n = 1;if (i >>> 16 == 0) { n += 16; i <<= 16; }if (i >>> 24 == 0) { n += 8; i <<= 8; }if (i >>> 28 == 0) { n += 4; i <<= 4; }if (i >>> 30 == 0) { n += 2; i <<= 2; }n -= i >>> 31;return n;
}/*** Format a long (treated as unsigned) into a character buffer.* @param val the unsigned int to format* @param shift the log2 of the base to format in (4 for hex, 3 for octal, 1 for binary)* @param buf the character buffer to write to* @param offset the offset in the destination buffer to start at* @param len the number of characters to write* @return the lowest character location used*/static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {int charPos = len;int radix = 1 << shift;int mask = radix - 1;do {buf[offset + --charPos] = Integer.digits[val & mask];val >>>= shift;} while (val != 0 && charPos > 0);return charPos;
}/*
* Package private constructor which shares value array for speed.
* this constructor is always expected to be called with share==true.
* a separate constructor is needed because we already have a public
* String(char[]) constructor that makes a copy of the given char[].
*/
String(char[] value, boolean share) {// assert share : "unshared not supported";this.value = value;
}
这篇关于Convert a Number to Hexadecimal的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!