Java の演算、数値演算、論理演算、ビット演算について話しましょう。これはプログラミングを学ぶ上で必ず必要となる理論的基礎です。
表 1. 二項算術演算子
最初の 4 つの演算子は何の疑問も抱かないはずです。すべては数学の場合と同じです。最後の演算子である除算の余りも、あまり複雑なことは行いません。たとえば、24 を 7 で割ると、3 つの整数と 3 つの余りが得られます。この演算子が返すのは剰余です。
二項演算子に加えて、Java には単項算術演算子があります。
表 2. 単項算術演算子:
単項プラスとマイナスの例:
インクリメントとデクリメントの操作は基本的に単純です。最初のケースでは変数が 1 増加し、2 番目のケースでは変数が 1 減少します。例は次のとおりです。
表 3. インクリメント/デクリメント演算子:
デモンストレーション:
算術演算に加えて、(2 つの数値の) 比較演算もあります。結果は常に true または false ( true / false ) になります。
表 4. 比較演算子
例:
表 5. 否定演算子の真理値表 (NOT)
表 6. 論理積演算子 (AND) の真理値表
表 7. 論理和演算子 (OR) の真理値表
表 8. モジュロ加算演算子 (XOR) の真理値表
Java にも同じ論理演算があります。
そして
ここで、短縮演算子 (
場合によっては、式の結果が最初のオペランドから計算されることがあります。これが、省略された演算子
短縮演算子の場合、式の 2 番目の部分は評価されません。ただし、これは式の結果が最初のオペランドからすでに明らかな場合にのみ発生します。
10 進数と 2 進数で 0 から 15 までを数える例を示します。
ご覧のとおり、すべてはそれほど複雑ではありません。ビットに加えて、バイト、キロバイト、メガバイト、ギガバイトなどのよく知られた情報単位もあります。おそらく、1 バイトに 8 ビットがあることはご存知でしょう。それはどういう意味ですか?これは、連続する 8 ビットが 1 バイトを占めることを意味します。以下にバイトの例を示します。
ほら、それはそれほど複雑ではありません。しかし、それでも、何かを明確にする必要があります。
例として 8 ビット数値を使用してこれを見てみましょう。
このアプローチはシンプルで、原理的には理解できます。ただし、数学的演算の実行が難しいという欠点もあります。たとえば、負の数と正の数を加算します。追加の操作を実行しない限り、折りたたむことはできません。
最初の行では、先行ゼロなしの 2 進数システムで値を取得しています。私たちには見えなくても、彼らはそこにいます。これは、すべてのビットが逆ビットに変換された 2 行目で証明されています。これが、これほど多くの主要なユニットが見られる理由です。これらは、最初の行に出力されたときにコンパイラによって無視された、以前の先行ゼロです。以下は、わかりやすくするために先頭のゼロも表示する小さなプログラムです。
今。右にシフトした数字については何と言えますか? それらは 2 で割り切れます。右に 1 ビットシフトするたびに、元の数値を 2 で割ります。数値が 2 で割り切れない場合、結果はマイナス無限大に向かって丸められます (下位)。しかし、これはビットを 1 だけシフトする場合にのみ機能します。そして 2 ビットの場合は 4 で除算します。3 ビットの場合は 8 で除算します。4 ビットの場合は 16 で除算します。わかりますか? 2 のべき乗...数値をビット単位で右
- Javaの演算子の種類は何ですか?
- JavaRush コースの Java オペレーター
- Java での数値演算
- Java の論理演算
- Java でのビット単位の演算
- Java での操作の優先順位
- 便利な使用例
Javaの演算子の種類は何ですか?
どのような操作でも、少なくとも 2 つのことが必要です。- オペレーター;
- オペランド。
JavaRush コースの Java オペレーター
いくつかの講義は、最初のクエストの第 4 レベルである Java 構文の Java 演算子に当てられています。特に、boolean などの条件演算子。このコースには、比較演算子、条件演算子、論理演算子の働きを理解するのに役立つ 22 のタスクが含まれています。Java での数値演算
プログラマーが数値に対して実行する最も一般的な操作は、数値を変数に代入することです。彼女はオペレーターと同様、=
あなたにとっても馴染みのある人物です。
int a = 1;
int b = 2;
int c = 3;
算術演算もあります。これらは二項算術演算子を使用して実行されます。
System.out.println(24 % 7); // prints 3
公式 Oracle ドキュメント サイトからの例を次に示します。 このプログラムは次を出力します: 1 + 2 = 3 3 - 1 = 2 2 * 2 = 4 4 / 2 = 2 2 + 8 = 10 10 % 7 = 3 Java では、次のことが可能です。たとえば、演算子の代入と算術演算子を組み合わせます。例を見てみましょう:
int x = 0;
x = x + 1; // x = 0 + 1 => x = 1
x = x + 1; // x = 1 + 1 => x = 2
x = x + 1; // x = 2 + 1 => x = 3
ここでは変数を定義しx
、値 0 を割り当てました。次に、各行で、x
変数の現在の値x
と 1 の合計に値を割り当てます。各行のコメントに説明があります。この手順は、変数の増加または増分と呼ばれます。上記の例のインクリメント操作は、演算子の組み合わせを使用して同様の操作に置き換えることができます。
int x = 0;
x += 1; // x = 0 + 1 => x = 1
x += 1; // x = 1 + 1 => x = 2
x += 1; // x = 2 + 1 => x = 3
代入演算子は任意の算術演算子と組み合わせることができます。
int x = 0;
x += 10; // x = 0 + 10 => x = 10
x -= 5; // x = 10 - 5 => x = 5
x *= 5; // x = 5 * 5 => x = 25
x /= 5; // x = 25 / 5 => x = 5
x %= 3; // x = 5 % 3 => x = 2;
最後の例がどのように機能するかを示してみましょう。
int x = 0;
x = (+5) + (+15); // Parentheses for clarity, it is possible without them
System.out.println("x = " + x);
int y = -x;
System.out.println("y = " + y);
int x = 9;
x++;
System.out.println(x); // 10
int y = 21;
y--;
System.out.println(y); // 20
これらの操作には、後置と接頭の 2 種類があります。最初のケースでは演算子は変数の後に記述され、2 番目のケースでは変数の前に記述されます。唯一の違いは、インクリメント操作またはデクリメント操作がいつ実行されるかです。以下の表に例と説明を示します。変数があるとします。
int a = 2;
それから:
int a = 1;
int b = 2;
boolean comparisonResult = a == b;
System.out.println("a == b :" + comparisonResult);
comparisonResult = a != b;
System.out.println("a != b :" + comparisonResult);
comparisonResult = a > b;
System.out.println("a > b :" + comparisonResult);
comparisonResult = a >= b;
System.out.println("a >= b :" + comparisonResult);
comparisonResult = a < b;
System.out.println("a < b :" + comparisonResult);
comparisonResult = a <= b;
System.out.println("a <= b :" + comparisonResult);
デモンストレーション:
Java の論理演算
それぞれの論理演算と真理値表を見てみましょう。- 否定演算 (
NOT
); - 結合演算、論理 AND (
AND
); - 論理和演算、論理 OR (
OR
); - モジュロ加算演算、排他的論理和 (
XOR
)。
!
— 否定演算子;&&
— 論理 AND 演算子 (短い)。||
— 論理 OR 演算子 (短い)。&
— ビット単位の AND 演算子。|
— ビットごとの OR 演算子。^
— ビットごとの排他的 OR 演算子。
public class LogicDemo {
public static void main(String[] args) {
notExample();
andExample();
orExample();
xorExample();
}
public static void notExample() {
System.out.println("NOT EXAMPLE:");
System.out.println("NOT false = " + !false);
System.out.println("NOT true = " + !true);
System.out.println();
}
public static void andExample() {
System.out.println("AND EXAMPLE:");
System.out.println("false AND false = " + (false & false));
System.out.println("false AND true = " + (false & true));
System.out.println("true AND false = " + (true & false));
System.out.println("true AND true = " + (true & true));
System.out.println();
}
public static void orExample() {
System.out.println("OR EXAMPLE:");
System.out.println("false OR false = " + (false | false));
System.out.println("false OR true = " + (false | true));
System.out.println("true OR false = " + (true | false));
System.out.println("true OR true = " + (true | true));
System.out.println();
}
public static void xorExample() {
System.out.println("XOR EXAMPLE:");
System.out.println("false XOR false = " + (false ^ false));
System.out.println("false XOR true = " + (false ^ true));
System.out.println("true XOR false = " + (true ^ false));
System.out.println("true XOR true = " + (true ^ true));
System.out.println();
}
}
このプログラムは次のように表示します。 NOT EXAMPLE: NOT false = true NOT true = false AND 例: false AND false = false false AND true = false true AND false = false true AND true = true OR 例: false OR false = false false OR true = true true OR false = true true OR true = true XOR 例: false XOR false = false false XOR true = true true XOR false = true true XOR true = false 論理演算子はboolean
変数にのみ適用されます。この例では値に直接適用しましたが、boolean
変数と一緒に使用することもできます。
boolean
表現については次のようになります。
&&
、||
) と同様のビット演算子 ( &
、|
) を使用できます。それらの違いは何ですか? まず、ビット単位は整数に適用できます。これについては後ほど説明します。そして第二に、省略されるものもあれば、省略されないものもあります。略語がどのようなものかを理解するために、次の式を見てみましょう。
false AND x = ?
true OR x = ?
これにはx
任意のブール値を指定できます。そして一般に、論理の法則と真理値表によれば、 truex
かfalseかに関係なく、最初の式の結果はfalseになり、2 番目の式の結果はtrueになります。見て。
&&
と を区別するものです||
。上記と同様の式では、2 番目のオペランドの値は評価されません。以下に小さな例を示します。
Java でのビット単位の演算
さて、ここからが最も興味深い部分であるビット単位の演算です。名前が示すように、これらはビットに対して実行される演算です。ただし、このトピックに入る前に、関連する領域について話しておく価値があります。2 進数系での数値の表現
数値は、プログラム内の他の情報と同様に、バイナリ コードでコンピュータ メモリに保存されます。バイナリ コードは 0 と 1 のセットです。それぞれの 0 または 1 は、ビットと呼ばれる情報の単位を表します。ウィキペディアによると:
ビット (英語の binary digit - 2 進数、言葉遊びでもあります: 英語の bit - 部分、粒子) は、情報量の測定単位です。1 ビットの情報は、オンまたはオフ、はいまたはいいえ、高または低、充電または充電されていないという 2 つの意味を持つシンボルまたは信号です。二進法では 1 (ワン) または 0 (ゼロ) です。ビット単位の演算子はどのような種類のデータを処理しますか?
Java のビット演算は整数に対してのみ実行されます。整数はビットのセットとしてコンピューターのメモリに保存されます。コンピューターはあらゆる情報を 2 進数システム (ビットのセット) に変換し、それから初めて情報を操作すると言えます。しかし、二進数体系はどのように機能するのでしょうか? 10 進数体系には、0、1、2、3、4、5、6、7、8、9 の 10 個の記号しかありません。私たちはこれらの記号を使って数を数えます。9 の次は 10、19 ~ 20 の次、99 ~ 100 の次、749 ~ 750 の次です。つまり、利用可能な 10 の記号の組み合わせを使用し、それらを使用して「0 から昼食まで」を数えることができます。2 進数システムでは、10 個の記号の代わりに、0、1 の 2 つだけがあります。しかし、10 進数システムと同じ原理に従ってこれらの記号を組み合わせることで、無限に数を数えることができます。
00000000 - 1 byte
10110010 - 1 byte
01011011 - 1 byte
1 バイト内のビットの反復しない組み合わせの数は 256 (2 8 = 256) です。しかし、Java に戻ってみましょう。このような整数データ型があります - byte
。この型は -128 から 127 までの値を取ることができ、コンピューター メモリ内の 1 つの数値はちょうど 8 ビット、つまり 1 バイトを占めます。このタイプの 1 つの数値は、ちょうど 1 つのbyte
コンピュータ メモリを占有します。そしてここで名前が一致するのは偶然ではありません。覚えているとおり、1 バイトには 256 個の異なる値を格納できます。そして、1 つのタイプ番号はbyte
256 の異なる値を取ることができます (負の値が 128、正の値が 127、ゼロが 1 つ)。各数値には、byte
8 ビットの一意のセットがあります。byte
これは type だけでなく、すべての整数型に当てはまります。タイプはbyte
最小のものを例として挙げています。以下の表は、すべての Java 整数型とそれらが占有するメモリ領域を示しています。 型について考えてみましょうint
。2147483648 個の負の値、2147483647 個の正の値、および 1 つのゼロを保存できます。合計:
2147483648 + 2147483647 + 1 = 4294967296.
このタイプはコンピュータのメモリで 32 ビットを占有します。32 個の 0 と 1 のセットから可能な組み合わせの数は次のとおりです。
232 = 4294967296.
型が保持できる値の数と同じ数int
。これは、データ型の値の範囲とそのサイズ (メモリ内のビット数) の関係を示す単なるデモンストレーションです。Java では任意の数の任意の型をバイナリに変換できます。Java 言語を使用してこれをいかに簡単に実行できるかを見てみましょう。type の例から学びますint
。この型には独自のラッパー クラスがありますInteger
。そして彼はtoBinaryString
私たちのためにすべての作業を行ってくれる を持っています:
int
この数値は 32 ビット必要です。ただし、上の例で数値 10 を出力すると、コンソールには 1010 と表示されますが、これは先頭のゼロが出力されないためです。これらが表示される場合、コンソールには 1010 の代わりに 00000000000000000000000000001010 が表示されますが、認識しやすくするために、先頭のゼロはすべて省略されています。「負の数はどうなるのでしょうか?」と自問するまでは、それほど難しいことではありません。二進法でのみ情報を認識します。マイナス記号もバイナリ コードで記述する必要があることがわかりました。これは、直接コードまたは補完コードを使用して実行できます。
ダイレクトコード
2 進数システムで数値を表現する方法。最上位ビット (左端のビット) が数値の符号に割り当てられます。数値が正の場合は左端のビットに 0 が書き込まれ、負の場合は - 1 が書き込まれます。追加コード
追加のコードを使用すると、直接コードの欠点を回避できます。数値の追加コードを取得する簡単なアルゴリズムがあります。数値 -5 の追加コードを取得してみましょう。この数値を 2 進数体系の 2 の補数コードを使用して表してみましょう。ステップ 1. 直接コードを使用して負の数の表現を取得します。-5 の場合、10000101 になります。 ステップ 2. 符号桁を除くすべての桁を反転します。すべての 0 を 1 に置き換え、左端のビットを除くすべての 1 を 0 に置き換えましょう。
10000101 => 11111010
ステップ 3. 結果の値に 1 を加算します。
11111010 + 1 = 11111011
準備ができて。2 の補数コードを使用して、2 進数システムで -5 の値を取得しました。Java は 2 の補数コードを使用して負の数をビット単位で格納するため、これは次の内容を理解するために重要です。
ビット演算の種類
すべての概要を説明したので、Java のビット単位の演算について話しましょう。ビット単位の演算は整数に対して実行され、その結果は整数になります。このプロセスでは、数値が 2 進数に変換され、各ビットに対して演算が実行され、結果が 10 進数に戻されます。演算のリストは次の表にあります。 すでにわかったように、数値はビットのセットとして表すことができます。ビット単位の演算は、そのような表現の各ビットに対して演算を実行します。NOT
、、、、AND
を見てみましょうOR
。XOR
最近、論理オペランドのみの真理値表を調べたことを思い出してください。この場合、同じ演算が整数の各ビットに適用されます。
ビット単位の単項演算子 NOT ~
この演算子は、すべての 0 を 1 に置き換え、すべての 1 を 0 に置き換えます。10進法で10という数字があるとします。2 進数では、この数値は 1010 です。この数値に単項ビットごとの否定演算子を適用すると、次のような結果が得られます。 Java コードでどのように見えるかを見てみましょう。public static void main(String[] args) {
int a = 10;
System.out.println(" a = " + a + "; binary string: " + Integer.toBinaryString(a));
System.out.println("~a = " + ~a + "; binary string: " + Integer.toBinaryString(~a));
}
次に、コンソールに何が表示されるかを見てみましょう。
ビット単位の AND 演算子
この演算子は 2 つの数値に適用されます。AND
各数値のビット間の演算を実行します。例を見てみましょう。 この演算は 2 つの数値に対して実行されます。Java コードの例:
ビット単位の OR 演算子
OR は 2 つの数値に適用されます。各数値のビット間で OR 演算を実行します。 これが IDEA でどのようになるかを見てみましょう。ビット演算、排他的論理和 (XOR)
同じ例を新しい操作で見てみましょう。 コード例:ビット単位で左シフト
この演算子は 2 つのオペランドに適用できます。つまり、演算ではx << y
、数値のビットの位置が左にx
シフトされます。y
それはどういう意味ですか?演算例を見てみましょう。10 << 1
演算結果は 10 進数の 20 になります。上の図からわかるように、すべてのビットが 1 だけ左にシフトされます。この操作中に、最上位ビット (左端のビット) の値が失われます。そして、最下位ビット (右端のビット) は 0 で埋められます。この作戦について何と言えますか?
-
数値のビットを左にビットずつシフトすることにより、数値を
X
2 N で乗算します。N
X
以下に例を示します。
-
しかし!値 1 のビットが左端の位置にある場合、数値の符号が変わる可能性があります。
-
無限に左にシフトすると、数値は単純に 0 になります。ポイント 2 と 3 を見てみましょう。
ビット単位で右シフト
この演算子は 2 つのオペランドに適用されます。それらの。演算ではx >> y
、数値のビットの位置が右にx
シフトします。y
別の例を見てみましょう。動作を概略的に分析してみましょう10 >> 1
。数値 10 のすべてのビットを 1 つ右にシフトしてみましょう。 シフト操作中に、右のビットが失われます。それらはただ消えていきます。左端のビットは数値の符号です (0 は正、1 は負)。したがって、最終的な値には、元の数値と同じように配置されます。負の数値の例: 右端のビットが失われ、左端のビットが数値の名誉符号として元の数値からコピーされます。IDEA でこれらすべてを行うにはどうすればよいでしょうか? 原則として、何も複雑なことはなく、単にそれを取得して移動するだけです。
X
にシフトする場合N
、数値をX
2 の 2 乗で割りますN
。デモンストレーション:
public class BitOperationsDemo {
public static void main(String[] args) {
for (int i = 1; i <= 10; i++) {
int shiftOperationResult = 2048 >> i;
int devideOperationResult = 2048 / (int) Math.pow(2, i);
System.out.println(shiftOperationResult + " - " + devideOperationResult);
}
}
}
何が起きてる?
-
変数 i を 1 から 10 までインクリメントするループ。
- 反復ごとに 2 つの値を計算します。
-
shiftOperationResult
数値 2048 を i ビット右にシフトした結果を変数に書き込みます。 -
devideOperationResult
数値 2048 を 2 の i 乗で割った結果を変数に書き込みます。 -
取得した 2 つの値をペアで表示します。
GO TO FULL VERSION