黑马程序员技术交流社区
标题: 基础班第一次考试关于位运算的发散思考 [打印本页]
作者: 球球_ 时间: 2015-9-7 23:51
标题: 基础班第一次考试关于位运算的发散思考
本帖最后由 球球_ 于 2015-9-8 22:49 编辑
第一次基础知识考试题有这么一道题(14题),其作用是输出一个数的2进制数,观察实现的代码发现其主要用到了位运算“<<”和“&”,实现的逻辑是用一个循环,将1依次移动31~~0位与输出的数取“与”,这样子就可以得到这个数的2进制数。
将问题发散一下,思考一个问题,可以输出8进制或者16进制吗?怎么输出?
我们知道一个数的8进制是将将其2进制从右到左,每次取三位,位数不够补0,因为是从右到左,为保证2进制输出与8进制输出的一致性,我们可以将上面1处的代码修改一下
for(int j = 0; j <32; j++)
if(((i<< j) & 1) != 0)--2
System.out.print("1");
else
System.out.print("0");
这样就可以反过来输出一个2进制数的每一位,我们再思考一个问题,怎么得到某一个bit位的值(0或1)?答案就是该位上的值(0或1)与1取与即可,该位上值为0,和1取与得0,该位上值为1,与1取与得1,图解如下:
............................0 ............................1
&000000000000001 & 000000000000001
结果为 000000000000000 000000000000001
也就是上面的2中的做法,依次右移与1取与得到i每一位上的值。
如果要得到连续两个bit位的值呢?与3(二进制0b11)取与,图解如下:
..........................10 .........................01
&000000000000011 &000000000000011
结果为 000000000000010 000000000000001
10结果仍是10,01结果仍是01.
这样就知道怎么求一个数的8进制了,8进制每一位是该数补码连续的三个bit位,将需要求出的三个bit位与7(二进制0b111)取与即可...
思路和步骤:【求8进制】
1. 我们先将判断x的值,如果为0,直接输出0
2. 将x与7进行与操作,其值就是x的8进制值的最低位。
3. 再将x无符号右移三位,在与7进行与操作其值就是x的8进制的倒数第2位
4. 继续无符号右移三位,直到相与结果为0. (为0以后,前面的位不用再计算)
5. 定义一个char数组来存放每次输出的值, 定义一个变量int pos记录下数组中输出位置。最后将数组打印出来。
我们给出代码:
public static void translateOctal(int num)
{
if(num ==0)
{
System.out.println(“0”);
}
char[] chs = {'0','1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7'};
char[] arr = new char[32];
int pos =arr.length – 1;
while(num != 0)
{
int temp = num & 7;
arr[pos--] = chs[temp];
num = num >>> 3;
}
for (int x = pos; x< arr.length; x++)
System.out.print(arr[x]);
System.out.println();
}
相同的道理,我们可以求出一个数的16进制。【求16进制】
思路和步骤:
1. 我们先将判断x的值,如果为0,直接输出0
2. 将x与15进行与操作,其值就是x的16进制值的最低位。
3. 再将x无符号右移四位,在与15进行与操作其值就是x的16进制的倒数第2位
4. 继续无符号右移四位,直到相与结果为0. (为0以后,前面的位不用再计算)
5. 定义一个char数组来存放每次输出的值, 定义一个变量int pos记录下数组中输出位置。最后将数组打印出来。
代码如下:
public static void translateHex(int num)
{
if(num ==0)
System.out.println("0");
char[] chs= {'0','1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9'
,'A' ,'B','C' ,'D' ,'E' ,'F' };
char[] arr= new char[32];
int pos =arr.length - 1;
while(num!= 0)
{
int temp= num & 15;
arr[pos--]= chs[temp];
num =num >>> 4;
}
for (int x= pos; x < arr.length; x++)
System.out.print(arr[x]);
System.out.println();
}
-
QQ图片20150907234800.png
(13.25 KB, 下载次数: 27)
考试题14
作者: 球球_ 时间: 2015-9-7 23:52
观察共性,我们发现转化为8进制和16进制的代码几乎是相似的,除了取与的数7和15,以及无符号右移的位数,我们将之抽象提取到一个方法里面,确定函数传入三个参数(数值、比较数、以及偏移位)。修改如下:
public static void translate(int num, int compareNumber, int offset)
{
if(num == 0)
{
System.out.println(“0”);
}
char[] chs = {'0','1' ,'2' ,'3' ,'4' ,'5' ,'6' ,'7' ,'8' ,'9' ,'A' ,
'B' ,'C' ,'D' ,'E' ,'F' };
char[] arr = new char[32];
int pos = arr.length – 1;
while(num != 0)
{
int temp = num & compareNumber;
arr[pos--] = chs[temp];
num = num >>> offset;
}
for (int x = pos; x < arr.length; x++)
System.out.print(arr[x]);
System.out.println();
}
这样,求2进制调用translate(x, 1, 1);
求8进制只需调用translate(x, 7, 3);
求16进制只需调用translate(x, 15, 4);即可实现代码
作者: shijinlong 时间: 2015-9-8 09:10
膜拜啊,大神,看的头发晕
作者: hpuwuxu 时间: 2015-9-8 14:36
哈哈,学的很深入
作者: fdhm 时间: 2015-9-10 01:05
大神,求带我啊
作者: zsj1992 时间: 2015-9-10 01:07
太牛了,现在都看不懂
作者: ZZBY 时间: 2015-9-10 01:12
位运算很神奇高效
八进制 》》》3后&
十六进制》》》4后&
作者: 横创 时间: 2015-9-10 01:28
看了就烦
作者: 且听风_R0pZK 时间: 2015-9-10 06:28
楼主这个程序很不错!毕老师的视频里面也曾经提炼过的。加油,共同进步哈
作者: thriver2010 时间: 2015-9-10 07:15
进制转换,转的头晕
作者: lishuaichen 时间: 2015-9-10 12:00
说的真好赞一个!!!!
作者: 横创 时间: 2015-9-13 11:28
恭喜楼主中奖了
作者: 周中侠 时间: 2015-9-13 22:23
牛,值得学习一下思想
作者: 球球_ 时间: 2015-9-20 00:29
给自己回个贴,点个赞
作者: 留不住 时间: 2015-9-21 15:36
挺不错的
作者: lu518627 时间: 2015-9-21 23:40





作者: heima0826xurui 时间: 2015-9-21 23:49
厉害呀!
作者: charlie 时间: 2015-9-22 00:24
很有用,谢谢!
作者: 江湖104 时间: 2015-9-22 00:50
很不错,学习了,加油
作者: xcvbzbvcx 时间: 2015-9-22 08:05
点个赞。。。。
作者: thriver2010 时间: 2015-9-22 09:15
大神啊,膜拜中
作者: 黑色雨季 时间: 2015-9-22 20:53
我来水了,,,,,,,,
作者: sfgjys 时间: 2015-9-22 22:43
我擦,膜拜啊,研究的这么深
作者: lichuang 时间: 2015-9-22 22:48
大神,你果然很牛逼
作者: hhhhxj 时间: 2015-9-22 23:04
厉害
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |