大家是如何读位运算符的???

jingulang 2008-06-21 05:25:15
大家是如何读位运算符的???

| ^ >> 这类东东 我一看就迷糊啊

我只知道书上讲这东西是按二进制讲的 莫非你们看到这类东西 先把十进制转为二进制在纸上看?

123123^50得多少?
123132>>5得多少?

你们是一看就知道结果吗?

我是一点感觉都没有

(不用算,随便按的几个数)

...全文
419 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
zbkiller 2009-01-05
  • 打赏
  • 举报
回复
UP UP
ZiSheng 2009-01-02
  • 打赏
  • 举报
回复
mark
sagezk 2008-06-22
  • 打赏
  • 举报
回复
诸位看看下面几个各等于多少
2147 >> 32
2147 >> 36
2147 >> -6
sagezk 2008-06-22
  • 打赏
  • 举报
回复
public class BitOpt {

public static void main(String[] args) {
int n = -61;
int a = 61; //00000000 00000000 00000000 00111101

r = a << 6;
//00000000 00000000 00000000 00111101 : 61 a
//00 00000000 00000000 00111101 XXXXXX //左面有6位移出丢弃了,后面空缺6位补0得到
//--------------------------------------------- <<
//00000000 00000000 00001111 01000000 : 3904 r

r = n >> 3;
//11111111 11111111 11111111 11000011 : -61 n
//XXX 11111111 11111111 11111111 11000 //右面有3位(011)移出丢弃了,前面高位面空缺3位如果移位前原数最高位为1则补1否则补0得到
//--------------------------------------------- >>
//11111111 11111111 11111111 11111000 : -8 r

r = n >>> 3;
//11111111 11111111 11111111 11000011 : -61 n
//XXX 11111111 11111111 11111111 11000 //右面有3位(011)移出丢弃了,前面高位面空缺3位补0得到
//--------------------------------------------- >>>
//00011111 11111111 11111111 11111000 : 536870904 r

System.out.println(r);

}

}
youzy 2008-06-22
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 sunyujia 的回复:]
一定要经常写汇编才行,楼上总结的很好,除了移位运算,其他位运算在10进制情况下目测确实太难了呵呵。
[/Quote]
  • 打赏
  • 举报
回复
[Quote=引用楼主 jingulang 的帖子:]
123123^50得多少?
123132>>5得多少?
[/Quote]

这种怎么可能一看就知道结果啊,就算一直做汇编的也不可能一眼就“看”出结果的

这个得转成二进制再进行异或和移位运算的,因为移位运算是给计算机用的,
不是给人用的,只要知道它们运算的原理就行了,没有必要采用手工计算。

下面这个代码段,输出这两个位运算的结果和二进制位数据:

public class Test {
public static void main(String[] args) {
System.out.println("123123^50 = " + (123123 ^ 50));
System.out.println(toFullBinaryString(123123));
System.out.println(toFullBinaryString(50));
System.out.println(toFullBinaryString(123123^50));
System.out.println();
System.out.println("123123>>5 = " + (123123>>5));
System.out.println(toFullBinaryString(123123));
System.out.println(toFullBinaryString(123123>>5));
}

private static String toFullBinaryString(int num) {
char[] chs = new char[Integer.SIZE];
for(int i = 0, k = chs.length; i < k; i++) {
chs[k - i - 1] = ((num >> i) & 1) == 0 ? '0' : '1';
}
return new String(chs);
}
}
sagezk 2008-06-22
  • 打赏
  • 举报
回复

public class BitOpt {

public static void main(String[] args) {
//位运算符共7个:& | ^ ~ << >> >>>
//计算规则,把二进制位1当作true,0当作false看待,按相应逻辑运算规则计算对应二进制位
//^ 按位异或规则为相同为0不同为1,即1-1和0-0得到0,1-0和0-1得到1
int r = 0;
int a = 61; //00000000 00000000 00000000 00111101
int b = -4; //11111111 11111111 11111111 11111100

r = a & b;
//00000000 00000000 00000000 00111101 : 61 a
//11111111 11111111 11111111 11111100 : -4 b
//--------------------------------------------- &
//00000000 00000000 00000000 00111100 : 60 r

r = a | b;
//00000000 00000000 00000000 00111101 : 61 a
//11111111 11111111 11111111 11111100 : -4 b
//--------------------------------------------- |
//11111111 11111111 11111111 11111101 : -3 r

r = a ^ b;
//00000000 00000000 00000000 00111101 : 61 a
//11111111 11111111 11111111 11111100 : -4 b
//--------------------------------------------- ^
//11111111 11111111 11111111 11000001 : -63 r

r = ~a;
//00000000 00000000 00000000 00111101 : 61 a
//--------------------------------------------- ~
//11111111 11111111 11111111 11000010 : -62 r
}

}
rypgood 2008-06-22
  • 打赏
  • 举报
回复
左右移动还好,就是对2的乘除操作
但是 或 非 与 异或 等等 这些才叫难啊
sagezk 2008-06-22
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 sagezk 的回复:]
诸位看看下面几个各等于多少
2147 >> 32
2147 >> 36
2147 >> -6
[/Quote]
大家请参见 16 17 18 楼 [火龙果] 的解释,想当年初学 Java 时被这个问题困扰过,后来也是翻遍了《Java语言规范》和《JVM规范》才找到答案。虽没什么实际的使用价值,但有时莫名其妙的 Bug 没准就是这个问题引发的,而且行踪诡异较难发现。
zidasine 2008-06-22
  • 打赏
  • 举报
回复
迷糊。。。学习了。。
网络咖啡 2008-06-22
  • 打赏
  • 举报
回复
123123^50得多少? 这个看不出来
123132>>5得多少? 这个可以看出来,因为右移一位相等于除2,这个相当于除2的5次方。
Sou2012 2008-06-22
  • 打赏
  • 举报
回复
¦ 按位或
^ 按位取反
>> 右移运算符
  • 打赏
  • 举报
回复
int 类型移位,num1 op num2 的结果相当于 num1 op (num2 & 31) 的结果
long 类型移位,num1 op num2 的结果相当于 num1 op (num2 & 63) 的结果
  • 打赏
  • 举报
回复
低 5 位或低 6 位的话对于正数还是可以用模 32、64 的方法来计算的,
对于负数只能一直加 32 或 64,直到大于等于 0 为止,这时得出的结果
就是所需要移动的位数。
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 sagezk 的回复:]
诸位看看下面几个各等于多少
2147 >> 32
2147 >> 36
2147 >> -6
[/Quote]

Java 虚拟机规范的移位指令中明确指出,int 类型进行 >>>、>>、<< 移位时,所移的位数是
第二个操作数低 5 位所表示的数值,相当于把第二个操作数进行了模 32 运算。

同样,long 类型进行这种操作,所移的位数是第二个操作数低 6 位所表示的数值,相当于把
第二个操作数进行了模 64 运算。

2147 >> 32 相当于 2147 >> 0,结果是 2147
2147 >> 36 相当于 2147 >> 4 的结果
2147 >> -6

-6 = ~6 + 1,可以得出二进制为 11111111111111111111111111111010,低 5 位是 11010,即 26
因此 2147 >> -6 相当于 2147 >> 26 的结果
sagezk 2008-06-21
  • 打赏
  • 举报
回复
先解释一下整数在内存中的存储形式:

public class BitOpt {

public static void main(String[] args) {
//int 类型变量共使用4个字节即32位二进制位存储
//其中最高位第32位为符号位,表示此整数是否有负号,0代表没有即正数1代表有负号即负数

int m = 61; //111101为其二进制表示形式
//正整数的存储形式:除第32位符号位为0外,其余31位是直接把此数的二进制表示形式通过补0补齐到31位得到的如下
// 0000000 00000000 00000000 00111101
//结合符号位0最终得到61在内存中的存储形式
//00000000 00000000 00000000 00111101

int n = -61;
//负整数的存储形式:除第32位符号位为1外,其余31位的处理稍复杂一些,如下
//1. 先得到此负数的绝对值61的二进制表示形式通过补0补齐到31位得到
// 0000000 00000000 00000000 00111101
//2. 在上面的基础上按位取反,即0变1,1变0,得到
// 1111111 11111111 11111111 11000010
//3. 在步骤2的基础上按二进制计算规则(逢二进一)加上1得到
// 1111111 11111111 11111111 11000011
//结合符号位1最终得到-61在内存中的存储形式
//11111111 11111111 11111111 11000011
}

}
sagezk 2008-06-21
  • 打赏
  • 举报
回复
!markit!
ldt_love_java 2008-06-21
  • 打赏
  • 举报
回复
先将要运算的数据转换为二进制然后再做相应的运算。
sunyujia 2008-06-21
  • 打赏
  • 举报
回复
一定要经常写汇编才行,楼上总结的很好,除了移位运算,其他位运算在10进制情况下目测确实太难了呵呵。
xinyuechenfu 2008-06-21
  • 打赏
  • 举报
回复
(有符号右移)>>右移将一个数右移n位相当于将该数除以2的n次方;2进制算法就是
1.如果n为正数那么就是在它化算成2进制以后为数全部向右移动一位,在他的最左面的高位上添加0;(有时会有溢出现象)
2.如果n为负数的话,是在它化算成2进制以后为数全部向右移动一位,在他的最左面的高位上添加1;
(按位或)|,就是将2个整数,转换成2进制,进行位比较,比如00101与11011,结果就是1111,也就是说0|1=1,0|1=1;1|0=1;0|1=1;1|1=1
(按位异或)^,其实与按位或有点相同,但是不同也相当打,如上面的例子,00101与11011,结果就是11110也就是说0|1=1,0|1=1;1|0=1;0|1=1;1|1=0;
注意它在2个相同的时候,结果都是0,

//------------------------------------

位操作符,可以与(=)等号联合使用,以便合并运算操作和赋值操作:|=,^=,&=(有点头疼的符号)都是合法的,由于~是一元操作符,所以不能与=联合使用。
加载更多回复(3)

62,615

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧