java语言对应数学中逻辑运算
"∧" 表示 "与" 对应java : &
"∨" 表示 "或" 对应java : |
"┐"表示 "非" 对应java : ~
a⊕b = (¬a ∧ b) ∨ (a ∧¬b) 异或(xor) 对应java : ^
在计算机中,数值一直以补码存储,运算也用补码。
ex:8bit signed int (-128~127),最高位为符号位,0000 0000 ~ 1111 1111 以补码形式存储 带符号数
0000 0000 :十进制0 1+(-1)=0,其实用的是1的补码和-1的补码相加。正数的补码为本身
0000 0001 :1(0+1) 即0000s 00001+?= 0000 0000 当?为1111 1111 时相加为1 0000 0000 最高位进位被舍弃
.... 由此诞生了-1在计算机中存储的二进制 1111 1111,即-1的补码
0111 1111 : 127 所有从 1~127 都有对应的-1~-127,一个数的补码+该数相反数的补码 = 0(1 0000 0000)
1000 0000 : -128 多出了 0000 0000 (0的补码)和 1000 0000 (-128的补码)
....
1111 1111 : -1 从-128(1000 0000)+1.... -1(11111 1111))+1 = 0 (0000 0000) +1.... 127 (0111 111)
验证计算机只会做加法,且带符号位(8 bit)整型范围(-128 ~127)
同时可以证明 负数的补码=相反数的补码按位取反+1
正数原码=补码=反码,涉及负数才有补码反码之间计算
原码:1010(-2)
补码:1110
补码 = (原码)按位取反+1(原码除符号位按位取反+1)
在位运算中计算得知补码后怎么转换为直观的原码
原码 = (补码 -1)后除符号位按位取反
原码 = 反码(补码除符号位取反) +1
Java中没有无符号数据类型,取最高位作为符号位表示正负数,但运算和位操作都使用补码计算
与运算 & 规则 :对应数的补码对应位都为1时结果位才为1
System.out.println( 7 & 9);//result为1
分析:
7的二进制:0111(即为源码也为补码)
9的二进制:1001
result :0001
System.out.println(-1&-2); //输出-2
分析:
-1原码:1001 对应补码:1111
-2原码:1010 对应补码:1110
result: 得到补码:1110(即负数补码,-2的补码)
1101 补码-1 或 1001 除符号位按位取反得反码
1010 按位取反得原码,即带符号的-2 1010 反码+1得原码 -2
同理或运算,异或运算,取反运算相同,都为对补码行运算
输出结果
或运算 | 规则:有一个位为1,则结果位为1
System.out.println(7 | 9);// 15
分析:
7的二进制:0111
9的二进制:1001
result :1111
异或运算 ^ 规则:对补码不同位不同为1
System.out.println( 7 & 9);//result为14//System.out.println((~7&9)|(7&~9));//结果相同
分析:
7的二进制:0111
9的二进制:1001
result :1110
取反运算 ~ 规则:对补码按位取反
System.out.println( ~7);//输出-8
分析:
7的二进制:0000 0000 0000 0000 0000 0000 0000 0111
正整数的原码=补码,然后对补码求反
result: 1111 1111 1111 1111 1111 1111 1111 1000 //符号位改变(第一位),取反之后变成负数了(即负数的补码)
1000 0000 0000 0000 0000 0000 0000 0111 //反码(除符号位取反)
1000 0000 0000 0000 0000 0000 0000 1000 //对反码+1(得原码)== -8
System.out.println( ~-7);//输出6
分析:
-7的二进制:1000 0000 0000 0000 0000 0000 0000 0111 //该为原码,计算机中存储,计算的为补码,需转换为补码再按位求反
result: 1111 1111 1111 1111 1111 1111 1111 1001 //补码
0000 0000 0000 0000 0000 0000 0000 0110 //对补码求反仍然为补码
// 但符号位为0 即正数,补码=原码 == 6
移位运算 << (有符号左移), >>(有符号右移) , >>>(无符号右移)
<< :左移后,低位补0
>> :右移后,正数高位补0,负数高位补1
>>> :无符号右移,高位都补0
a << n 左移n位,值为a*2^n
a >> n 右移n位,值为a/2^n