请用移位的方式打印出一个十进制整数的十六进制形式。提示:按每4个二进制位对整数进行移位和去高位处理,得到的结果就是十六进制数的一位,然后按下面三种方式之一(作为作业,要求每种方式都用到)计算出一个十六进制数值对应的十六进制形式
定义一个数组,其中包含0-F这些字符,然后用要计算的数值作为数组的索引号,即可获得其对应的十六进制数据。 public class Test4 {/** Creates a new instance of Test1 */
public Test4() {
}
public void printMe(){
System.out.println("Hello world");
}
public static void main(String[] args) {
System.out.println(getHexString(23));
}
public static String getHexString(int number){
char[] hex={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
StringBuffer sb=new StringBuffer("0x");
int mask=0xF;
for(int i=7;i>=0;i--){
int temp=number>>(i*4);
temp=temp&mask;
sb.append(hex[temp]);
}
return sb.toString();
}
}
那位大哥能给我讲讲那个temp&mask是干嘛的,为啥要这样啊?
还有sb.append(hex【temp】)这一步是干嘛的?谁能给我讲懂啊,我实在是看不懂,请高手给我指教指教啊,我都想了一天了也弄不懂啊,拜托了啊

解决方案 »

  1.   

    temp & mask 是取 temp 的低 4 位数据的。如果能在纸上画一下程序执行过程中各数值二进制位的变化,那你马上就能够明白是怎么回事了。
      

  2.   

    int temp=number>>(i*4);
    temp=temp&mask;
    sb.append(hex[temp]);第一句表示获得十进制数number向右移动4*i位后的结果,这句话你明白吧?
    也就是通过循环逐次获取int型数的32位(每次取出4位)mask=0xF表示一个4位的数1111 (十六进制F表示二进制1111)
    第二句话地意思是temp的低四位。
    因为上面一行 number>>(i*4) 将获得一个32位的整形temp
    而我们只需要其中的低4位,所以采用与操作,将自动将高于低四位的部分置0 (自动补充mask的位置为0,与操作的话计算得到0,这步与操作的实际意义就是获得temp的低4位)第三句,将temp表示的4位二进制数转换成十六进制(从数组中读取字符),这个能明白吧然后将它添加到字符串中(sb最开始初始化为0x也即十六进制字符串的开头,用来表示十六进制)LZ还有什么不明白的吗?
      

  3.   

    我不明白为什么要取第四位啊,就是这不明白?
    还有就是hex[temp]不明白
      

  4.   

    &是在2进制状态下按位与操作,比如:
    5 & 6, 2进制下5是0101,6是0110,0101 & 0110 = 0100
    所以 5 & 6 = 4temp & mask
    mask = 0XF, 2进制下是 00000000 00000000 00000000 00001111
    这样任何一个整数跟mask进行与操作,都会只剩下最后4位
    所以temp & mask 得到的结果跟 temp%16 是一样的当temp成为 一个0到15的数以后,用它作为hex数组的下标,hex[temp]中的字符就刚好是0~15在16进制下的表示。
    把它们拼接起来,用sb.append()拼接起来,就可以得到最后结果了。
      

  5.   

    比如你的样例 23
    它的二进制表示是:
    0000 0000 0000 0000 0000 0000 0001 0111循环在 i 为1 和 0 的时候有实际作用 (其他时,temp为0 这里不做探究)i==1时, temp = number >> 4 = 0000 0000 0000 0000 0000 0000 0000 0001
    这里取低四位和不取没有什么区别i==0时, temp = number >> 0 = 0000 0000 0000 0000 0000 0000 0001 0111
    注意,此时如果不取低四位则不符合代码本意
    所以必须取低四位不知道这样说LZ理解了没有 = =
      

  6.   

    hex数组中存的是16进制数表示时能取的字符hex[i]表示1位16进制数的表示比如 2 在 16进制下的表示为 2
        10 在 16进制下的表示为 A
    以此类推
      

  7.   

    对于int(int是4个字节32位)的0xF,二进制是 0000 0000 0000 0000 0000 0000 0000 1111
    可以看出,任何int跟这个0xF进行&运算,只有二进制的最后4位(也就是低)有效,二进制的高28位计算结果都会变成0,所以也就相当于保留int的低4位,去除int的高28位sb.append(hex[temp])就是把数组hex的下标为temp(这个是计算得到的一个数)的数组元素添加到sb这个字符串缓存对象里。这个帖子几年前好像就有人问了
    http://topic.csdn.net/u/20080328/11/8e9a992d-96d3-4edd-89ff-764b584a915c.html不过现在就帖子的链接打不开。
      

  8.   

    首先,LZ了解十六进制数的表示吗?二进制数的表示?
    十六进制数表示
    0 -> 0
    1 -> 1
    2 -> 2
    3 -> 3
    4 -> 4
    5 -> 5
    6 -> 6
    7 -> 7
    8 -> 8
    9 -> 9
    10 -> A
    11 -> B
    12 -> C
    13 -> D
    14 -> E
    15 -> F比如 1F = 1 * 16 + 15 = 31,这个LZ明白吧?计算机为了区分各各进制数的差别,人为的在数之前加了符号以区别
    如16进制前加0x,8进制前加0,这只是为了区分进制  OK?你的程序的输出结果是一个8位的16进制数
    为什么是8位?
    首先,一个int类型整数为32位二进制,而每4位二进制数可以转换为1位16进制数
    为什么?想想 4位二进制数可以表示的数的范围
    从 0000 到 1111 也即 0 到 15 也即 十六进制下的 0 到 F!  OK?于是,你的程序的思路就是,将number的32位每4位切割,将4位二进制数转成16进制,然后将8位拼接起来,输出字符串这个时候你应该已经注意到 hex字符数组的作用
    对于任意的i (i >= 0, i <= 15) 十进制数i的十六进制表示为 hex[i]
    比如 当i=10, 十进制数10的十六进制表示为 A 也就是 hex[10]
    这样你明白hex字符数组的用处了吧?循环中
    temp = number >> (i * 4);
    通过循环变量i,逐次取出number的4位二进制数,保存到temp中
    比如,令number= 0101 0000 0111 1010 0011 1001 0001 1111
    那么 当i=7, temp = number >> 28 将number向右移位28位
    对于右移操作,最高位补0(这里不讨论负数、逻辑等问题,有兴趣自己网上搜吧)
    于是,temp = number >> 28 = 0000 0000 0000 0000 0000 0000 0000 0101
    看,temp的低4位正是 number的 0 到 3 位 0101.
    依次循环正好可以取遍number的每4位  LZ 这里明白了吗  码字好累 = =再说 int mask = 0xF
    首先,mask为int型,故它为32位二进制数
    而0xF为一个十六进制数(0x部分的解释上面已经说了)
    0xF = 15 = 1111(二进制)
    所以 mask的完整表示为 0000 0000 0000 0000 0000 0000 0000 1111
    OK?循环的第二步 temp = temp & mask
    注意 与操作中,每一位上,只要有0 则与操作的结果为0  OK?
    于是无论temp的值是多少, 前28位的结果都是0 OK?
    而 与1之后,结果为原来的值( 0 & 1 = 0, 1 & 1 = 1)
    所以 这一步的语义就是:保留temp的低四位! OK?你可能要问,为什么只要低4位?
    因为我们说过,每一次循环只处理number的4位
    如果不与mask,会有什么结果?
    令number= 0101 0000 0111 1010 0011 1001 0001 1111
    temp = number >> 24 = 0000 0000 0000 0000 0000 0000 0101 0000
    不与mask,则 temp的值为 temp = 1 * 64 + 1 * 16 = 80!
    这不仅不符合我们程序的目的,更重要的是,hex数组的下标允许最大值为15,传80进去将会抛出数组下标超界的异常! OK?sb.append(hex[temp]);
    首先LZ明白 hex[temp]的意思了吧?
    就是根据取出的4位二进制数temp的值(0 到 15),得到其16进制表示(0 到 F)
    sb.append(char) 表示,将char加入到字符串的末尾于是循环结束之后,就完成了将number每4位转为16进制并添加到字符串中,返回它的16进制表示呼  = = 累。PS:关于为什么10进制数可以这样转成16进制
    首先,计算机中存储数都是存它的2进制表示的
    也即一个整形 t = 7 ,实际它是以 0111形式存的 
    而由于正好 4位2进制数可以转成16进制,所以这就给我们转换16进制形成了便利!