「java位运算实例」java位运算详解

博主:adminadmin 2022-12-21 02:57:08 74

本篇文章给大家谈谈java位运算实例,以及java位运算详解对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。

本文目录一览:

Java中的这几个位运算符有大神讲解一下不?最好举生活中的例子,谢谢!

/**

我通俗点说:在位运算里面,其实大多数都是进行二进制运算的,也就是0和1,之间的运算!

以下例子里面:0代表假,1代表真;

按位与:  

真与真=真;(11=1)

假与假=假;(00=0)

真与假=假;(10=0)

假与真=假 ;(01=0)

总结(在按位与里面,逢假(0)必假(0));

-----------------------------------------------------------------

按位或:|  

真与真=真;(1|1=1)

假与假=假;(0|0=0)

真与假=假;(1|0=1)

假与真=假 ;(0|1=1)

总结(在按位或里面,逢真(1)必真(1));

-----------------------------------------------------------------

按位异或:^ 

真与真=真;(1^1=0)

假与假=假;(0^0=0)

真与假=假;(1^0=1)

假与真=假;(0^1=1)

总结(在按位或里面,相同就(0)不同则(1));

----------------------------------------------------------------

按位非~

这个我思前想后了很久,我觉得我不好更通俗的讲解;

(请原谅,我尽可能的保持通俗)

我要是跟你讲这个,你需要了解一点基本知识,才比较好理解一点!

你了解这个:(源码--反码---补码),我比较好讲一点!

a:所有字面值常量(你暂时理解基本数字):他们在内存里面存储的时候,都是以二进制的补码形式存在的!

b:不管正数还是负数,在内存里面存储都是补码!

c:不同点就是:正数的源码,反码,补码,都一样!

d:负数则不一样,一个负数的补码,是该正数的源码---逐位取反---然后末尾+1---得到的就是该负数在内存里面存储的形式(补码)!

e:正数的最高位,即(最左边第一位是0,其他位有效值位),负数的最高位,即(最左边第一位是1,其他位是有效数值位!)

好了,基本知识我说完了,不好意思我只有这能力了,能不能看懂完全看造化了!

---进入主题:

按位非,是一元运算符:

它的作用是一把个数字的补码,逐位取反,得到另外一个数字的补码!这个我觉得需要举例比较容易理解一点:

例子:假如(非5:~5),因为5是正数,所以5的二进制在内存里面形式都一样,举短一点的吧,byte类型,8位!

0 0 0 0 0 1 0 1---5的二进制;

1 1 1 1 1 0 1 0---按位非~,0变1,1变0(变完以后,这个是另外一个数字的补码,因为是负数,我们不好看,但是我们可以还原他的正数,就知道该数是几了!)

0 0 0 0 0 1 0 0---按照上面d步骤逆向过来,末尾-1---逐位取反---得到该数正数的原码!

所以你看这个数字有效位是4;所以,上面的那个负数补码就是-4,总结( ~5 = -4 );

我天,我都尽可能说详细了...还是觉得怕你看不明白!

--------------------------------------------------------------------------------

左移:(理解是乘法,2的n次幂,2是底数!)---低位补零

52=20   等价 5x(2x2)=20

63=48   等价 6x(2x2x2)=48

44=64   等价 4x(2x2x2x2)=64

右移:(理解是除法,倍率同上)----如果是正数,在高位补零,如果是负数,则在高位补1

82=2    等价  8÷(2x2)=2;

163=2   等价  16÷(2x2x2)=2;

-163=-2 等价  -16÷(2x2x2)=-2;

无符号右移(和右移是一回事,区别在后面)---不管正负数:高位都是补0;

163=2   等价  16÷(2x2x2)=2;

-163=-2 等价  16÷(2x2x2)=2;

(不管正负还是负数,结果都是正数,懂了?这就是无符号右移的区别!)

-------------------------------------------------------------------------------

这些知识都是非常基础的知识,很关键,也很重要,如果我说的你看不懂,也没关系,你可以跳过这一步,向后面学习

学一段时间后,在回头看看..会恍然大悟的!!

不好意思解答能力有限:不足之处还请路人..指点!!

*/

JAVA位运算怎么用的???

Java 位运算 Java 位运算[转]一,Java 位运算1.表示方法: 在Java语言中,二进制数使用补码表示,最高位为符号位,正数的符号位为0,负数为1。补码的表示需要满足如下要求。 (l)正数的最高位为0,其余各位代表数值本身(二进制数)。 (2)对于负数,通过对该数绝对值的补码按位取反,再对整个数加1。2.位运算符 位运算表达式由操作数和位运算符组成,实现对整数类型的二进制数进行位运算。位运算符可以分为逻辑运算符(包括~、&、|和^)及移位运算符(包括、)。1)左移位运算符()则将运算符左边的运算对象向右移动运算符右侧指定的位数。“有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1。3)Java也添加了一种“无符号”右移位运算符(),它使用了“零扩展”:无论正负,都在高位插入0。这一运算符是C或C++没有的。

java的位运算

根据你提供的结果判断,你说的这个“11000011"数,不是二进制,是个十进制吧。

你把11000011化成二进制补码,然后右移两位。把结果再转换为十进制就是“2750002”了。

java中使用补码表示二进制,正数的补码是其本身,负数的补码是它的绝对值取反+1:

例如:

+3 二进制位0000 0011(最高位为符号位,0正,1负),补码为:0000 0011;

-3 绝对值二进制位0000 0011,求反为1111 1100,补码为1111 1101

对-32 ===== 1111 11012 结果为1111 1111(为补码) 化成十进制为-1;

可能说的不够详细,仅供参考。。。。

java中的位运算符及其用法。

位逻辑运算符有“与”(AND)、“或”(OR)、“异或(XOR)”、“非(NOT)”,分别用“”、“|”、“^”、“~”表示。

下面的例子说明了位逻辑运算符:

// Demonstrate the bitwise logical operators.

class BitLogic {

public static void main(String args[]) {

String binary[] = {

"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",

"1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"

};

int a = 3; // 0 + 2 + 1 or 0011 in binary

int b = 6; // 4 + 2 + 0 or 0110 in binary

int c = a | b;

int d = a b;

int e = a ^ b;

int f = (~a b) | (a ~b);

int g = ~a 0x0f;

System.out.println(" a = " + binary[a]);

System.out.println(" b = " + binary[b]);

System.out.println(" a|b = " + binary[c]);

System.out.println(" ab = " + binary[d]);

System.out.println(" a^b = " + binary[e]);

System.out.println("~ab|a~b = " + binary[f]);

System.out.println(" ~a = " + binary[g]);

}

}

在本例中,变量a与b对应位的组合代表了二进制数所有的 4 种组合模式:0-0,0-1,1-0,和1-1。“|”运算符和“”运算符分别对变量a与b各个对应位的运算得到了变量c和变量d的值。对变量e和f的赋值说明了“^”运算符的功能。字符串数组binary代表了0到15对应的二进制的值。在本例中,数组各元素的排列顺序显示了变量对应值的二进制代码。数组之所以这样构造是因为变量的值n对应的二进制代码可以被正确的存储在数组对应元素binary[n]中。例如变量a的值为3,则它的二进制代码对应地存储在数组元素binary[3]中。~a的值与数字0x0f (对应二进制为0000 1111)进行按位与运算的目的是减小~a的值,保证变量g的结果小于16。因此该程序的运行结果可以用数组binary对应的元素来表示。该程序的输出如下:

a = 0011

b = 0110

a|b = 0111

ab = 0010

a^b = 0101

~ab|a~b = 0101

~a = 1100

左移运算符

左移运算符使指定值的所有位都左移规定的次数。它的通用格式如下所示:

value num

这里,num指定要移位值value移动的位数。也就是,左移运算符使指定值的所有位都左移num位。每左移一个位,高阶位都被移出(并且丢弃),并用0填充右边。这意味着当左移的运算数是int类型时,每移动1位它的第31位就要被移出并且丢弃;当左移的运算数是long类型时,每移动1位它的第63位就要被移出并且丢弃。

在对byte和short类型的值进行移位运算时,你必须小心。因为你知道Java在对表达式求值时,将自动把这些类型扩大为 int型,而且,表达式的值也是int型 。对byte和short类型的值进行移位运算的结果是int型,而且如果左移不超过31位,原来对应各位的值也不会丢弃。但是,如果你对一个负的byte或者short类型的值进行移位运算,它被扩大为int型后,它的符号也被扩展。这样,整数值结果的高位就会被1填充。因此,为了得到正确的结果,你就要舍弃得到结果的高位。这样做的最简单办法是将结果转换为byte型。下面的程序说明了这一点:

// Left shifting a byte value.

class ByteShift {

public static void main(String args[]) {

byte a = 64, b;

int i;

i = a 2;

b = (byte) (a 2);

System.out.println("Original value of a: " + a);

System.out.println("i and b: " + i + " " + b);

}

}

该程序产生的输出下所示:

Original value of a: 64

i and b: 256 0

因变量a在赋值表达式中,故被扩大为int型,64(0100 0000)被左移两次生成值256(10000 0000)被赋给变量i。然而,经过左移后,变量b中惟一的1被移出,低位全部成了0,因此b的值也变成了0。

既然每次左移都可以使原来的操作数翻倍,程序员们经常使用这个办法来进行快速的2的乘法。但是你要小心,如果你将1移进高阶位(31或63位),那么该值将变为负值。下面的程序说明了这一点:

// Left shifting as a quick way to multiply by 2.

class MultByTwo {

public static void main(String args[]) {

int i;

int num = 0xFFFFFFE;

for(i=0; i4; i++) {

num = num 1;

System.out.println(num);

}

}

}

该程序的输出如下所示:

536870908

1073741816

2147483632

-32

初值经过仔细选择,以便在左移 4 位后,它会产生-32。正如你看到的,当1被移进31位时,数字被解释为负值。

右移运算符

右移运算符使指定值的所有位都右移规定的次数。它的通用格式如下所示:

value num

这里,num指定要移位值value移动的位数。也就是,右移运算符使指定值的所有位都右移num位。

下面的程序片段将值32右移2次,将结果8赋给变量a:

int a = 32;

a = a 2; // a now contains 8

当值中的某些位被“移出”时,这些位的值将丢弃。例如,下面的程序片段将35右移2次,它的2个低位被移出丢弃,也将结果8赋给变量a:

int a = 35;

a = a 2; // a still contains 8

用二进制表示该过程可以更清楚地看到程序的运行过程:

00100011 35

2

00001000 8

将值每右移一次,就相当于将该值除以2并且舍弃了余数。你可以利用这个特点将一个整数进行快速的2的除法。当然,你一定要确保你不会将该数原有的任何一位移出。

右移时,被移走的最高位(最左边的位)由原来最高位的数字补充。例如,如果要移走的值为负数,每一次右移都在左边补1,如果要移走的值为正数,每一次右移都在左边补0,这叫做符号位扩展(保留符号位)(sign extension),在进行右移操作时用来保持负数的符号。例如,–8 1 是–4,用二进制表示如下:

11111000 –8

1

11111100 –4

一个要注意的有趣问题是,由于符号位扩展(保留符号位)每次都会在高位补1,因此-1右移的结果总是–1。有时你不希望在右移时保留符号。例如,下面的例子将一个byte型的值转换为用十六进制表示。注意右移后的值与0x0f进行按位与运算,这样可以舍弃任何的符号位扩展,以便得到的值可以作为定义数组的下标,从而得到对应数组元素代表的十六进制字符。

// Masking sign extension.

class HexByte {

static public void main(String args[]) {

char hex[] = {

'0', '1', '2', '3', '4', '5', '6', '7',

'8', '9', 'a', 'b', 'c', 'd', 'e', 'f''

};

byte b = (byte) 0xf1;

System.out.println("b = 0x" + hex[(b 4) 0x0f] + hex[b 0x0f]);

}

}

该程序的输出如下:

b = 0xf1

无符号右移

正如上面刚刚看到的,每一次右移,运算符总是自动地用它的先前最高位的内容补它的最高位。这样做保留了原值的符号。但有时这并不是我们想要的。例如,如果你进行移位操作的运算数不是数字值,你就不希望进行符号位扩展(保留符号位)。当你处理像素值或图形时,这种情况是相当普遍的。在这种情况下,不管运算数的初值是什么,你希望移位后总是在高位(最左边)补0。这就是人们所说的无符号移动(unsigned shift)。这时你可以使用Java的无符号右移运算符,它总是在左边补0。下面的程序段说明了无符号右移运算符。在本例中,变量a被赋值为-1,用二进制表示就是32位全是1。这个值然后被无符号右移24位,当然它忽略了符号位扩展,在它的左边总是补0。这样得到的值255被赋给变量a。

int a = -1;

a = a 24;

下面用二进制形式进一步说明该操作:

11111111 11111111 11111111 11111111 int型- 1的二进制代码

24 无符号右移24位

00000000 00000000 00000000 11111111 int型255的二进制代码由于无符号右移运算符只是对32位和64位的值有意义,所以它并不像你想象的那样有用。因为你要记住,在表达式中过小的值总是被自动扩大为int型。这意味着符号位扩展和移动总是发生在32位而不是8位或16位。这样,对第7位以0开始的byte型的值进行无符号移动是不可能的,因为在实际移动运算时,是对扩大后的32位值进行操作。下面的例子说明了这一点:

// Unsigned shifting a byte value.

class ByteUShift {

static public void main(String args[]) {

char hex[] = {

'0', '1', '2', '3', '4', '5', '6', '7',

'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'

};

byte b = (byte) 0xf1;

byte c = (byte) (b 4);

byte d = (byte) (b 4);

byte e = (byte) ((b 0xff) 4);

System.out.println(" b = 0x"

+ hex[(b 4) 0x0f] + hex[b 0x0f]);

System.out.println(" b 4 = 0x"

+ hex[(c 4) 0x0f] + hex[c 0x0f]);

System.out.println(" b 4 = 0x"

+ hex[(d 4) 0x0f] + hex[d 0x0f]);

System.out.println("( b 0xff) 4 = 0x"

+ hex[(e 4) 0x0f] + hex[e 0x0f]);

}

}

该程序的输出显示了无符号右移运算符对byte型值处理时,实际上不是对byte型值直接操作,而是将其扩大到int型后再处理。在本例中变量b被赋为任意的负byte型值。对变量b右移4位后转换为byte型,将得到的值赋给变量c,因为有符号位扩展,所以该值为0xff。对变量b进行无符号右移4位操作后转换为byte型,将得到的值赋给变量d,你可能期望该值是0x0f,但实际上它是0xff,因为在移动之前变量b就被扩展为int型,已经有符号扩展位。最后一个表达式将变量b的值通过按位与运算将其变为8位,然后右移4位,然后将得到的值赋给变量e,这次得到了预想的结果0x0f。由于对变量d(它的值已经是0xff)进行按位与运算后的符号位的状态已经明了,所以注意,对变量d再没有进行无符号右移运算。

B = 0xf1

b 4 = 0xff

b 4 = 0xff

(b 0xff) 4 = 0x0f

位运算符赋值

所有的二进制位运算符都有一种将赋值与位运算组合在一起的简写形式。例如,下面两个语句都是将变量a右移4位后赋给a:

a = a 4;

a = 4;

同样,下面两个语句都是将表达式a OR b运算后的结果赋给a:

a = a | b;

a |= b;

下面的程序定义了几个int型变量,然后运用位赋值简写的形式将运算后的值赋给相应的变量:

class OpBitEquals {

public static void main(String args[]) {

int a = 1;

int b = 2;

int c = 3;

a |= 4;

b = 1;

c = 1;

a ^= c;

System.out.println("a = " + a);

System.out.println("b = " + b);

System.out.println("c = " + c);

}

}

该程序的输出如下所示:

a = 3

b = 1

c = 6

java的位运算求解

42949672942147483247(后者为Java整型可存储最大整数),所以你这个数应该是声明应该是:

long num = 4294967294L;

那么此数的二进制码是:

0000 0000 0000 0000 0000 0000 0000 0000 01111111 11111111 11111111 11111111

用你声明的数值左移33位,它会变成一个负数。

java位运算实例的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java位运算详解、java位运算实例的信息别忘了在本站进行查找喔。

The End

发布于:2022-12-21,除非注明,否则均为首码项目网原创文章,转载请注明出处。