數(shù)字轉換為十六進制數(shù)
給定一個整數(shù)聪黎,編寫一個算法將這個數(shù)轉換為十六進制數(shù)可都。對于負整數(shù)耕姊,我們通常使用 補碼運算 方法膀值。
注意:
- 十六進制中所有字母(a-f)都必須是小寫棍丐。
- 十六進制字符串中不能包含多余的前導零误辑。如果要轉化的數(shù)為0,那么以單個字符'0'來表示歌逢;對于其他情況巾钉,十六進制字符串中的第一個字符將不會是0字符。
- 給定的數(shù)確保在32位有符號整數(shù)范圍內(nèi)秘案。
- 不能使用任何由庫提供的將數(shù)字直接轉換或格式化為十六進制的方法砰苍。
示例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);
}
}
- 數(shù)字與字符轉換可以通過
ASCII碼
進行轉換赚导。數(shù)字0對應的ASCII碼值為48,字母A對應的ASCII碼為65讨惩,字母a對應的ASCII碼為97辟癌。 - 在32位有符號整數(shù)下,
0xffffffff
對應的原碼與-1
的補碼相同荐捻,所以使用(long)Math.pow(2, 32) + num
來代替負數(shù)的補碼黍少。 - 查看題解,本題主要考察
位運算
处面,對位運算還缺乏理解厂置,還需要深入學習。
優(yōu)秀位運算題解:
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)
著作權歸作者所有魂角。商業(yè)轉載請聯(lián)系作者獲得授權昵济,非商業(yè)轉載請注明出處。
對數(shù)字的每四位與15(即2進制中的1111or16進制中的f)進行與運算野揪,得出的結果就是這一位的值访忿。最后的推出條件位num = 0,即為0000時退出斯稳,數(shù)字轉換完成海铆。
以下為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源代碼中也基本是這種思想。我們需要從源碼中學習的還有很多挣惰。