四 运算符的基本操作B
/**
* 4、逻辑运算符 与 位运算符
* 逻辑运算:
* &&、||、!、^、&、|
* 注1:逻辑运算符用于对boolean型结果的表达式进行运算,运算的结果都是boolean型 。
* 注2:&和&&以及|和||的区别在于:
* 如果使用&&或||,那么当"&&"的左边为false("||"左边表达式为true),则将不会计算其右边的表达式.
* 如果使用&或|,那么无论任何情况,&或|两边的表达式都会参与计算.
*
* 位运算符:
* &、|、^、~、>>、<<、>>>
* &,|,^除了可以作为逻辑运算符,也可以做为位算符,它们对两个操作数中的每一个二进制位都进行运算.
* 只有参加运算的两位都为1,&运算的结果才为1,否则就为0。
* 只有参加运算的两位都为0,|运算的结果才为0,否则就为1。
* 只有参加运算的两位不同,^运算的结果才为1,否则就为0。
* 我们可以对数据按二进制位进行移位操作,java的移位运算符有三种:
* << 左移(二进制位数后面补0)
* >> 右移(正数的二进制为前面补0,负数的二进制为前面补1)
* >>> 无符号右移(无论正负的二进制位前面均补0)
* 移位运算符适用类型有byte、short、char、int、long
* 对与低于int型的操作数将先自动转换为int型再移位。
* 对于int型整数移位a>>b,系统先将b对32取模,得到的结果才是真正移位的位数。例如:a>>33和a>>1结果是一样的,a>>32的结果还是a原来的数字。
* 对于long型整数移位时a>>b ,则是先将移位位数b对64取模。
* x>>1的结果和x/2的结果是一样的,x<<2和x*4的结果也是一样的。总之,一个数左移n位,就是等于这个数乘以2的n次方,一个数右移n位,就是等于这个数除以2的n次方。
* 请思考:如何用程序实现求2的x次方。答案:y = 1<< x;
*/
public class OperatorTest2
{
public int itest = 0;
public boolean testShort(int i)//测试短路与和短路或的函数体
{
if(i > 0)
{
itest = i;
return true;
}
else
{
return false;
}
}
public static void main(String[] args)
{
/*逻辑运算真值表*/
System.out.println("逻辑运算真值表");
System.out.println(
"true && true = " + (true&&true) + "/n" +
"true && false = " + (true&&false) + "/n" +
"false && true = " + (false&&false) + " 短路与:右边的false不参加运算" + "/n" +
"false && false = " + (false&&false) + " 短路与:右边的true不参加运算"
);
System.out.println(
"true || true = " + (true||true) + " 短路或: 右边的true不参加运算" + "/n" +
"true || false = " + (true||false) + " 短路或: 右边的false不参加运算" + "/n" +
"false || true = " + (false||false) + "/n" +
"false || false = " + (false||false)
);
System.out.println(
"true & true = " + (true&true) + "/n" +
"true & false = " + (true&false) + "/n" +
"false & true = " + (false&false) + "/n" +
"false & false = " + (false&false)
);
System.out.println(
"true | true = " + (true|true) + "/n" +
"true | false = " + (true|false) + "/n" +
"false | true = " + (false|false) + "/n" +
"false | false = " + (false|false)
);
System.out.println(
"! true = " + (!true) + "/n" +
"! false = " + (!false)
);
System.out.println(
"true ^ true = " + (true^true) + " 只有两者相同才返回true" + "/n" +
"true ^ false = " + (true^false) + "/n" +
"false ^ true = " + (false^false) + "/n" +
"false ^ false = " + (false^false) + " 只有两者相同才返回true"
);
/*短路与和短路或的应用*/
OperatorTest2 oper = new OperatorTest2();
System.out.println("短路与和短路或");
if(oper.testShort(12) && oper.testShort(23)){}
//因为&&左边的式子testShort(12)传入的12大于0,结果为true,所以程序将继续执行&&右边的testShort(23),并将23传给itest,因此最后打印23
System.out.println(oper.itest);
oper.itest = -23;
if(oper.testShort(-1)&& oper.testShort(21)){}
//因为&&左边的式子testShort(-1)传入的-1小于0,结果为false,所以程序将结束&&语句,打印先前我们给itest传入的-23.
System.out.println(oper.itest);
oper.itest = 0;
if(oper.testShort(-1)|| oper.testShort(23)){}
//因为||左边的式子testShort(-1)传入的-1小于0,结果为false,所以程序将继续执行||右边的testShort(23),并将23传给itest,因此最后打印23
System.out.println(oper.itest);
if(oper.testShort(12) || oper.testShort(23)){}
//因为||左边的式子testShort(12)传入的12大于0,结果为true,所以程序将结束||语句,并将12传递给itest.,因此最后打印12.
System.out.println(oper.itest);
System.out.println("与和或");
if(oper.testShort(12) & oper.testShort(23)){}
System.out.println(oper.itest);//23
if(oper.testShort(-1)& oper.testShort(23)){}
System.out.println(oper.itest);//23
if(oper.testShort(-1)| oper.testShort(23)){}
System.out.println(oper.itest);//23
if(oper.testShort(12) | oper.testShort(23)){}
System.out.println(oper.itest);//23
//由于无论&或|左边和右边的式子都要执行,所以最后的结果均是23
/*位运算符*/
System.out.println(" /"0,1/"表");
/**
* 注意:
* 这里进行的是位运算,而不是逻辑运算,java中逻辑运算只能操作true和false
* 而位运算只能操作char byte short int long五种数据类型.
* 区别:
* &、|、^这几个运算符,既是逻辑运算符也可以作为位运算符,
* 当他们操作的是true和false时,他们就是逻辑"与、或、异或"
* 当他们操作的是整数类型的数值时,他们就是位运算符.
*/
System.out.println(
"1 & 1 = " + (1&1) + "/n" +
"1 & 0 = " + (1&0) + "/n" +
"0 & 1 = " + (0&1) + "/n" +
"0 & 0 = " + (0&0)
);
System.out.println(
"1 | 1 = " + (1|1) + "/n" +
"1 | 0 = " + (1|0) + "/n" +
"0 | 1 = " + (0|1) + "/n" +
"0 | 0 = " + (0|0)
);
System.out.println(
"1 ^ 1 = " + (1^1) + "/n" +
"1 ^ 0 = " + (1^0) + "/n" +
"0 ^ 1 = " + (0^1) + "/n" +
"0 ^ 0 = " + (0^0)
);
System.out.println(
"~1 = " + (~1) + "/n"+
"~0 = " + (~0)
);
/*解释上面的结果*/
//0的十六进制数是0x00 00 00 00
//1的十六进制数是0x00 00 00 01
System.out.println("解释上边的/"0,1/"表");
Integer integers1 = 0x00000000;
Integer integers2 = 0x00000001;
System.out.println("打印0&1");
System.out.println(Integer.toBinaryString(integers1 & integers2));//0x00 00 00 00
System.out.println(Integer.toHexString(integers1 & integers2));//0x00 00 00 00
//0x00 00 00 00 & 0x00 00 00 01 = 0x00 00 00 00
System.out.println("打印0|1");
System.out.println(Integer.toBinaryString(integers1 | integers2));//0x00 00 00 01
System.out.println(Integer.toHexString(integers1 | integers2));//0x00 00 00 01
//0x00 00 00 00 | 0x00 00 00 01 = 0x00 00 00 01
System.out.println("打印0^1");
System.out.println(Integer.toBinaryString(integers1 ^ integers2));//0x00 00 00 01
System.out.println(Integer.toHexString(integers1 ^ integers2));//0x00 00 00 01
//0x00 00 00 00 ^ 0x00 00 00 01 = 0x00 00 00 01
System.out.println("打印~1");
System.out.println(Integer.toBinaryString(~integers2));
System.out.println(Integer.toHexString(~integers2));
//~ 0x00 00 00 01 = 0xff ff ff fe = -2(10)
System.out.println("打印~0");
System.out.println(Integer.toBinaryString(~integers1));
System.out.println(Integer.toHexString(~integers1));
//~ 0x00 00 00 00 = 0xff ff ff ff = -1(10)
/**java中int类型数值的二进制规范*/
System.out.println("java中二进制规范");
System.out.println(Integer.toBinaryString(Integer.MAX_VALUE));
System.out.println(Integer.toHexString(Integer.MAX_VALUE));
System.out.println(Integer.MAX_VALUE);//7fffffff(31位1,去掉符号位 2的31次方=2147483647)
System.out.println(Integer.toBinaryString(Integer.MIN_VALUE));
System.out.println(Integer.toHexString(Integer.MIN_VALUE));
System.out.println(Integer.MIN_VALUE);//80000000(首位符号位为1,后跟31位0.2的32次方 = -2147483648)
//通过以上程序可知:
//由于java中的int是带符号的数值类型.
//所以从0x00 00 00 00到0x7f ff ff ff表示正数范围.(7的二进制数0111)
// 从0xff ff ff ff到0x80 00 00 00表示负数范围.(8的二进制数1000)
/*移位运算符*/
System.out.println("移位运算符: 正数移位");
Integer integers = 0x00000001;
System.out.println(integers<<1);//结果为2,左移1位 0x00 00 00 02
System.out.println(integers>>1);//结果为0,右移1位0x00 00 00 00
System.out.println(integers>>>1);//结果为0,无符号右移一位0x00 00 00 00
System.out.println("解释正数移位");
System.out.println(integers.toHexString(integers<<1));//左移1位 0x00 00 00 02
System.out.println(integers.toHexString(integers>>1));//右移1位0x00 00 00 00
System.out.println(integers.toHexString(integers>>>1));//无符号右移一位0x00 00 00 00
System.out.println("移位运算符: 负数移位");
integers = -1;//0xff ff ff ff
System.out.println(integers<<1);//结果为-2,左移1位 0xff ff ff fe
System.out.println(integers>>1);//结果为-1,右移1位0xff ff ff ff
System.out.println(integers>>>1);//结果为MAX_VALUE,无符号右移1为 0x7f ff ff ff
System.out.println("解释负数移位");
System.out.println(integers.toHexString(integers<<1));//左移1位 0xff ff ff fe(e的二进制位1110)
System.out.println(integers.toHexString(integers>>1));//右移1位0xff ff ff ff
System.out.println(integers.toHexString(integers>>>1));//无符号右移1为 0x7f ff ff ff(7的二进制位0111)
/*移位运算符的内部操作*/
/*对与低于int型的操作数将先自动转换为int型再移位*/
System.out.println("byte类型的移位测试");
byte bytes = 0x7f;//0111 1111
System.out.println(bytes<<2);//.... 0001 1111 1100 = 508
//虽然byte类型的最大值是0x7f,左移2为后会超出他的最大范围,但是不会报错,因为byte在移位运算时自动转换为int.(这点同算术运算符)
/*
* 对于int型整数移位a>>b,系统先将b对32取模,得到的结果才是真正移位的位数。
* 例如:a>>33和a>>1结果是一样的,a>>32的结果还是a原来的数字。
* 对于long型整数移位时a>>b ,则是先将移位位数b对64取模。
*/
System.out.println("移位的取模原理");
char ch = 255;
System.out.println(
(ch>>1) + " , " +
(ch>>(16+1)) + " , " +
(ch>>(32+1))
);
byte by = 127;
System.out.println(
(by>>1) + " , " +
(by>>(8+1)) + " , " +
(by>>(32+1))
);
short sh = 255;
System.out.println(
(sh>>1) + " , " +
(sh>>(16+1)) + " , " +
(sh>>(32+1))
);
int in = Integer.MAX_VALUE;
System.out.println(
(in>>1) + " , " +
(in>>(32+1))
);
long lg = Long.MAX_VALUE;
System.out.println(
(lg>>1) + " , " +
(lg>>(32+1)) + " , " +
(lg>>(64+1))
);
//通过以上实例证明int以下类型移位运算时是对32求模的
//而long类型的移位是对64求模的.
/*通过移位实现2的n次方*/
System.out.println("通过移位实现2的n次方效果");
for(int i = 0;i < 10; i++)
{
integers = i;
System.out.print((1<<integers) + " , ");
}
}
}
/* ~~Console out ~~
逻辑运算真值表
true && true = true
true && false = false
false && true = false 短路与:右边的false不参加运算
false && false = false 短路与:右边的true不参加运算
true || true = true 短路或: 右边的true不参加运算
true || false = true 短路或: 右边的false不参加运算
false || true = false
false || false = false
true & true = true
true & false = false
false & true = false
false & false = false
true | true = true
true | false = true
false | true = false
false | false = false
! true = false
! false = true
true ^ true = false 只有两者相同才返回true
true ^ false = true
false ^ true = false
false ^ false = false 只有两者相同才返回true
短路与和短路或
23
-23
23
12
与和或
23
23
23
23
"0,1"表
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0
1 ^ 1 = 0
1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0
~1 = -2
~0 = -1
解释上边的"0,1"表
打印0&1
0
0
打印0|1
1
1
打印0^1
1
1
打印~1
11111111111111111111111111111110
fffffffe
打印~0
11111111111111111111111111111111
ffffffff
java中二进制规范
1111111111111111111111111111111
7fffffff
2147483647
10000000000000000000000000000000
80000000
-2147483648
移位运算符: 正数移位
2
0
0
解释正数移位
2
0
0
移位运算符: 负数移位
-2
-1
2147483647
解释负数移位
fffffffe
ffffffff
7fffffff
byte类型的移位测试
508
移位的取模原理
127 , 0 , 127
63 , 0 , 63
127 , 0 , 127
1073741823 , 1073741823
4611686018427387903 , 1073741823 , 4611686018427387903
通过移位实现2的n次方效果
1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 , 512 ,
*/