Java Gossip: 邏輯、位元運算
来源:互联网 发布:淘宝凑单满减之后退货 编辑:程序博客网 时间:2024/05/08 20:43
大於、小於的運算會了,但如果想要同時進行兩個以上的條件判斷呢?例如分數大於80但小於90的判斷,在邏輯上有所謂的「且」、「或」與「反」,在 Java中也提供這幾個基本邏輯運算所需的「邏輯運算子」(Logical operator),分別為「且」(&&)、 「或」(||)及「反相」(!)三個運算子。
來看看下面這個程式會輸出什麼?
三段程式分別會輸出true、false與true三種狀況。
接下來看看「位元運算子」(Bitwise operator),在 數位設計上有AND、OR、XOR與補數等運算,在Java中提供這些運算的就是位元運算子,它們的對應分別是 AND (&)、OR(|)、XOR(^)與補數(~)。
如果您不會基本的位元運算,以下可以提供一個程式來顯示各個運算的結果:
執行結果:
AND運算:
0 AND 0 0
0 AND 1 0
1 AND 0 0
1 AND 1 1
OR運算:
0 OR 0 0
0 OR 1 1
1 OR 0 1
1 OR 1 1
XOR運算:
0 XOR 0 0
0 XOR 1 1
1 XOR 0 1
1 XOR 1 0
Java中的位元運算是逐位元運算的,例如10010001與01000001作AND運算,是一個一個位元對應運算,答案就是00000001;而補數 運算是將所有的位元0變1,1變0,例如00000001經補數運算就會變為11111110,例如下面這個程式所示:
這個程式會在主控台顯示-1,因為byte佔記憶體一個位元組,它儲存的0在記憶體中是00000000,經補數運算就變成11111111,這在電腦中 用整數表示則是-1。
要注意的是,邏輯運算子與位元運算子也是很常被混淆的,像是&&與 &,||與|,初學時可得多注意。
位元運算對初學者來說的確較不常用,但如果用的恰當的話,可以增進不少程式效率,例如下面這個程式可以判斷使用者的輸入是否為奇數:
執行結果:
請輸入數字: 8
是否為奇數? 否
這個程式得以運算的原理是,奇數的數值若以二進位來表示,其最右邊的位元必為1,而偶數最右邊的位元必為0,所以我們使用1來與輸入的值作AND運算,由 於1除了最右邊的位元為1之外,其它位元都會是0,與輸入數值AND運算的結果,只會留下最右邊位元為0或為的結果,其它部份都被0 AND運算遮掉了,這就是所謂「位元遮罩」,例如:
00000100 -> 4
00000001 -> 1
----------
00000000 -> 判斷為偶數
00000011 -> 3
00000001 -> 1
----------
00000001 -> 判斷為奇數
XOR的運算較不常見,這邊舉個簡單的XOR字元加密例子,先看看程式:
執行結果:
before encoding:A
after encoding:F
decoding:A
0x7是Java中整數的16進位寫法,其實就是10進位的7,將位元與1作XOR的作用其實就是位元反轉,0x7的最右邊三個位元為1,所以其實就是反 轉ch的最後三個位元,如下所示:
01000001 -> 65 -> 對應ASCII中的'A'
00000111 -> 0x7
----------
01000110 -> 70 -> 對應ASCII中的'F'
同樣的,這個簡單的XOR字元加密,要解密也只要再進行相同的位元反轉就可以了。
要注意的是,雖然在說明時都只取8個位元來說明,但實際的位元在運算時,需依資料型態所佔的記憶體長度而定,例如在使用int型態的0作運算時,要考慮的 是32個位元,而不是只有8個位元,因為int佔有4個位元組。
在位元運算上,Java還有左移(<<)與右移(>>)兩個運算子,左移運算子會將所有的位元往左移指定的位 數,左邊被擠出去的位元會被丟棄,而右邊會補上0;右移運算則是相反,會將所有的位元往右移指定的位數,右邊被擠出去的位元會被丟棄,至於左邊位元補0或 補1 則視最左邊原來的位元而定,如果原來是0就補0,是1就補1,您還可以使用>>>運算子,這個運算子在右移後一行在最左邊補上0。
可以使用左移運算來作簡單的2次方運算示範,如下所示:
執行結果:
2的0次: 1
2的1次: 2
2的2次: 4
2的3次:8
實際來左移看看就知道為何可以如此運算了:
00000001 -> 1
00000010 -> 2
00000100 -> 4
00001000 -> 8
來看看下面這個程式會輸出什麼?
int number = 75;
System.out.println((number > 70 && number < 80));
System.out.println((number > 80 || number < 75));
System.out.println(!(number > 80 || number < 75));
System.out.println((number > 70 && number < 80));
System.out.println((number > 80 || number < 75));
System.out.println(!(number > 80 || number < 75));
三段程式分別會輸出true、false與true三種狀況。
接下來看看「位元運算子」(Bitwise operator),在 數位設計上有AND、OR、XOR與補數等運算,在Java中提供這些運算的就是位元運算子,它們的對應分別是 AND (&)、OR(|)、XOR(^)與補數(~)。
如果您不會基本的位元運算,以下可以提供一個程式來顯示各個運算的結果:
- BitwiseOperator.java
public class BitwiseOperator { public static void main(String[] args) { System.out.println("AND運算:"); System.out.println("0 AND 0\t\t" + (0 & 0)); System.out.println("0 AND 1\t\t" + (0 & 1)); System.out.println("1 AND 0\t\t" + (1 & 0)); System.out.println("1 AND 1\t\t" + (1 & 1)); System.out.println("\nOR運算:"); System.out.println("0 OR 0\t\t" + (0 | 0)); System.out.println("0 OR 1\t\t" + (0 | 1)); System.out.println("1 OR 0\t\t" + (1 | 0)); System.out.println("1 OR 1\t\t" + (1 | 1)); System.out.println("\nXOR運算:"); System.out.println("0 XOR 0\t\t" + (0 ^ 0)); System.out.println("0 XOR 1\t\t" + (0 ^ 1)); System.out.println("1 XOR 0\t\t" + (1 ^ 0)); System.out.println("1 XOR 1\t\t" + (1 ^ 1)); } }
執行結果:
AND運算:
0 AND 0 0
0 AND 1 0
1 AND 0 0
1 AND 1 1
OR運算:
0 OR 0 0
0 OR 1 1
1 OR 0 1
1 OR 1 1
XOR運算:
0 XOR 0 0
0 XOR 1 1
1 XOR 0 1
1 XOR 1 0
Java中的位元運算是逐位元運算的,例如10010001與01000001作AND運算,是一個一個位元對應運算,答案就是00000001;而補數 運算是將所有的位元0變1,1變0,例如00000001經補數運算就會變為11111110,例如下面這個程式所示:
byte number = 0;
System.out.println((int)(~number));
System.out.println((int)(~number));
這個程式會在主控台顯示-1,因為byte佔記憶體一個位元組,它儲存的0在記憶體中是00000000,經補數運算就變成11111111,這在電腦中 用整數表示則是-1。
要注意的是,邏輯運算子與位元運算子也是很常被混淆的,像是&&與 &,||與|,初學時可得多注意。
位元運算對初學者來說的確較不常用,但如果用的恰當的話,可以增進不少程式效率,例如下面這個程式可以判斷使用者的輸入是否為奇數:
- BitWiseOperator.java
import java.util.Scanner; public class BitwiseOperator { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.print("請輸入數字: "); int inputedNumber = scanner.nextInt(); System.out.println("是否為奇數? " + ((inputedNumber&1) != 0 ? '是' : '否')); }}
執行結果:
請輸入數字: 8
是否為奇數? 否
這個程式得以運算的原理是,奇數的數值若以二進位來表示,其最右邊的位元必為1,而偶數最右邊的位元必為0,所以我們使用1來與輸入的值作AND運算,由 於1除了最右邊的位元為1之外,其它位元都會是0,與輸入數值AND運算的結果,只會留下最右邊位元為0或為的結果,其它部份都被0 AND運算遮掉了,這就是所謂「位元遮罩」,例如:
00000100 -> 4
00000001 -> 1
----------
00000000 -> 判斷為偶數
00000011 -> 3
00000001 -> 1
----------
00000001 -> 判斷為奇數
XOR的運算較不常見,這邊舉個簡單的XOR字元加密例子,先看看程式:
- XorCode.java
public class XorCode { public static void main(String[] args) { char ch = 'A'; System.out.println("before encoding:" + ch); ch = (char)(ch^0x7); System.out.println("after encoding:" + ch); ch = (char)(ch^0x7); System.out.println("decoding:" + ch); } }
執行結果:
before encoding:A
after encoding:F
decoding:A
0x7是Java中整數的16進位寫法,其實就是10進位的7,將位元與1作XOR的作用其實就是位元反轉,0x7的最右邊三個位元為1,所以其實就是反 轉ch的最後三個位元,如下所示:
01000001 -> 65 -> 對應ASCII中的'A'
00000111 -> 0x7
----------
01000110 -> 70 -> 對應ASCII中的'F'
同樣的,這個簡單的XOR字元加密,要解密也只要再進行相同的位元反轉就可以了。
要注意的是,雖然在說明時都只取8個位元來說明,但實際的位元在運算時,需依資料型態所佔的記憶體長度而定,例如在使用int型態的0作運算時,要考慮的 是32個位元,而不是只有8個位元,因為int佔有4個位元組。
在位元運算上,Java還有左移(<<)與右移(>>)兩個運算子,左移運算子會將所有的位元往左移指定的位 數,左邊被擠出去的位元會被丟棄,而右邊會補上0;右移運算則是相反,會將所有的位元往右移指定的位數,右邊被擠出去的位元會被丟棄,至於左邊位元補0或 補1 則視最左邊原來的位元而定,如果原來是0就補0,是1就補1,您還可以使用>>>運算子,這個運算子在右移後一行在最左邊補上0。
可以使用左移運算來作簡單的2次方運算示範,如下所示:
- ShiftOperator.java
public class ShiftOperator { public static void main(String[] args) { int number = 1; System.out.println( "2的0次: " + number); number = number << 1; System.out.println("2的1次: " + number); number = number << 1; System.out.println("2的2次: " + number); number = number << 1; System.out.println("2的3次:" + number); } }
執行結果:
2的0次: 1
2的1次: 2
2的2次: 4
2的3次:8
實際來左移看看就知道為何可以如此運算了:
00000001 -> 1
00000010 -> 2
00000100 -> 4
00001000 -> 8
转载地址:http://caterpillar.onlyfun.net/Gossip/JavaGossip-V1/LogicalBitwiseOperator.htm
- Java Gossip: 邏輯、位元運算
- java位元算
- JAVA位元算的应用
- 位元算符号
- Java Gossip: throw、throws
- Java Gossip: autoboxing、 unboxing
- Java Gossip: Statement、 ResultSet
- Gossip
- Gossip
- Java Gossip: 套件(package)
- Java Gossip: Arrays 的copyOf()
- Java Gossip: 內部類別(Inner class)
- Java Gossip学习笔记 (一)
- Java Gossip学习笔记 (二)
- 帝國二十六位元帥
- c 语言 进制、位元
- Java Gossip: 使用正則表示式(Regular expression)
- Gossip简介
- 网友的表情键盘
- linux认识和分析日志文件
- 设计模式简介
- Makefile的automake生成(升级版)
- jvm学习笔记(一)
- Java Gossip: 邏輯、位元運算
- 深度学习:Hinton_Science_Reducing the dimensionality of data with neural networks
- wordpress中的RSS
- php脚本(功能发邮件;技术mongodb队列,锁文件。linux运行)
- 嵌入式,很高兴认识你
- Android之开发常用颜色
- CodeBlocks创建和使用共享库
- 分享一个外国人写的微处理器设计书
- Linux系统内存使用率总结