# 位元運算子

> 了解位元運算子(& | ^)與位移運算子(<< >> >>>)的基本使用。

## 位元運算子

我們知道資料在記憶體中都是以0/1的方式儲存，如果想直接對這些位元做運算，Java提供了一些位元運算子供設計師使用。

| Operator運算子 | 描述                    | 範例 (令a, b為數值) |
| ----------- | --------------------- | ------------- |
| \~          | 位元補數(complement)運算    | \~a           |
| &           | 位元和(and)運算            | a & b         |
| \|          | 位元或(or)運算             | a \| b        |
| ^           | 位元互斥或(exclusive or)運算 | a ^ b         |

## 補數 complement (\~)：

補數的意思就是1變0，0變1，反向的感覺。

範例程式：

```java
int a = 45;
System.out.println(a);
a = ~a;
System.out.println(a);
```

執行結果：

```java
45    // 00000000000000000000000000101101
-46   // 11111111111111111111111111010010
```

## 和 and (&)：

和運算，是二元運算，只有兩個都為1，結果才是1。

範例程式：

```java
int a = 45;
int b = 25;
System.out.println(a & b);
```

執行結果：

```java
//   a = 00000000000000000000000000101101
//   b = 00000000000000000000000000011001
9    //  00000000000000000000000000001001
```

AND真值表：

| **&** | **1** | **0** |
| ----- | ----- | ----- |
| **1** | 1     | 0     |
| **0** | 0     | 0     |

## 或 or (|)：

或運算，是二元運算，只要有一個1，結果就是1。

範例程式：

```java
int a = 45;
int b = 25;
System.out.println(a | b);
```

執行結果：

```java
//  a = 00000000000000000000000000101101
//  b = 00000000000000000000000000011001
61  //  00000000000000000000000000111101
```

OR 真值表：

| **\|** | **1** | **0** |
| ------ | ----- | ----- |
| **1**  | 1     | 1     |
| **0**  | 1     | 0     |

## 互斥或 exclusive or (^)：

互斥或，英文縮寫常稱『XOR』，是二元運算子，位元不同為1。

程式範例：

```java
int a = 45;
int b = 25;
System.out.println(a ^ b);
```

執行結果；

```java
// a = 00000000000000000000000000101101
// b = 00000000000000000000000000011001
52  // 00000000000000000000000000110100
```

XOR 真值表：

| **^** | **1** | **0** |
| ----- | ----- | ----- |
| **1** | 0     | 1     |
| **0** | 1     | 0     |

## 位移運算子 Bit Shift Operators

位移運算子的目的是向左或向右移動目標運算元的每個位元。

| Operator運算子 | 描述         | 範例 (令a, b為數值)        |   |
| ----------- | ---------- | -------------------- | - |
| <<          | 保留正負號的左移運算 | a << b (將a逐位元左移b個單位) |   |
| >>          | 保留正負號的右移運算 | a >> b (將a逐位元右移b個單位) |   |
| >>>         | 右移運算       | a >>> b              |   |

範例程式：

```java
int a = 16;
int b = 2;
System.out.println(a << b);
System.out.println(a >> b);
System.out.println(a >>> b);
```

執行結果：

```java
// a = 00000000000000000000000000010000
64  // 00000000000000000000000001000000
4   // 00000000000000000000000000000100
4   // 00000000000000000000000000000100
```

範例程式2 (負號測試)：

```java
int a = -16;
int b = 2;
System.out.println(a << b);
System.out.println(a >> b);
System.out.println(a >>> b);
```

執行結果：

```java
       //  a = 11111111111111111111111111110000
-64         // 11111111111111111111111111000000
-4          // 11111111111111111111111111111100
1073741820  // 00111111111111111111111111111100
```

(無號右移>>>，不會理會當前的符號位元，直接右移補0上去)

### ※利用位元位移運算子，可以達到最快的 \*2 或 /2 運算。

嘛，因為根本沒做到數學運算，而乘法跟除法在計算上是很廢時的。

範例程式：

```java
int a = 3;
System.out.println(a * 2 * 2 * 2 * 2 * 2);  
System.out.println(a << 5);

int b = 20000;
System.out.println(b / 2 / 2 / 2 / 2 / 2);
System.out.println(b >> 5);
```

執行結果：

```java
96
96
625
625
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://yubin551.gitbook.io/java-note/basic_java_programming/operator/bitwise_operators.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
