JavaRush /Java Blog /Random-JA /Java 演算子の概要: 論理演算、算術演算、ビット演算

Java 演算子の概要: 論理演算、算術演算、ビット演算

Random-JA グループに公開済み
Java の演算、数値演算、論理演算、ビット演算について話しましょう。これはプログラミングを学ぶ上で必ず必要となる理論的基礎です。 Java 演算子の概要: 論理、算術、ビット単位 - 1

Javaの演算子の種類は何ですか?

どのような操作でも、少なくとも 2 つのことが必要です。
  • オペレーター;
  • オペランド。
演算子の例としては、2 つの数値を加算する演算における単純なプラスが挙げられます。この場合、加算された数値がオペランドになります。したがって、演算子の助けを借りて、1 つ以上のオペランドに対して演算を実行します。2 つのオペランドに対して演算を実行する演算子はバイナリと呼ばれます。たとえば、2 つの数値を加算します。単一のオペランドに対して演算を実行する演算子は単項と呼ばれます。たとえば、単項マイナスです。

JavaRush コースの Java オペレーター

いくつかの講義は、最初のクエストの第 4 レベルである Java 構文の Java 演算子に当てられています。特に、boolean などの条件演算子。このコースには、比較演算子、条件演算子、論理演算子の働きを理解するのに役立つ 22 のタスクが含まれています。

Java での数値演算

プログラマーが数値に対して実行する最も一般的な操作は、数値を変数に代入することです。彼女はオペレーターと同様、=あなたにとっても馴染みのある人物です。
int a = 1;
int b = 2;
int c = 3;
算術演算もあります。これらは二項算術演算子を使用して実行されます。
表 1. 二項算術演算子
Java 演算子の概要: 論理、算術、ビット単位 - 2最初の 4 つの演算子は何の疑問も抱かないはずです。すべては数学の場合と同じです。最後の演算子である除算の余りも、あまり複雑なことは行いません。たとえば、24 を 7 で割ると、3 つの整数と 3 つの余りが得られます。この演算子が返すのは剰余です。
System.out.println(24 % 7); // prints 3
公式 Oracle ドキュメント サイトからの例を次に示します。 Java 演算子の概要: 論理、算術、ビット単位 - 3このプログラムは次を出力します: 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;
最後の例がどのように機能するかを示してみましょう。
Java 演算子の概要: 論理、算術、ビット単位 - 4
二項演算子に加えて、Java には単項算術演算子があります。
表 2. 単項算術演算子:
Java 演算子の概要: 論理、算術、ビット単位 - 4単項プラスとマイナスの例:
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);
Java 演算子の概要: 論理、算術、ビット単位 - 6
インクリメントとデクリメントの操作は基本的に単純です。最初のケースでは変数が 1 増加し、2 番目のケースでは変数が 1 減少します。例は次のとおりです。
int x = 9;
x++;
System.out.println(x); // 10

int y = 21;
y--;
System.out.println(y); // 20
これらの操作には、後​​置と接頭の 2 種類があります。最初のケースでは演算子は変数の後に記述され、2 番目のケースでは変数の前に記述されます。唯一の違いは、インクリメント操作またはデクリメント操作がいつ実行されるかです。以下の表に例と説明を示します。変数があるとします。
int a = 2;
それから:
表 3. インクリメント/デクリメント演算子:
Java 演算子の概要: 論理、算術、ビット単位 - 5デモンストレーション:
Java 演算子の概要: 論理、算術、ビット単位 - 8
算術演算に加えて、(2 つの数値の) 比較演算もあります。結果は常に true または false ( true / false ) になります。
表 4. 比較演算子
Java 演算子の概要: 論理、算術、ビット単位 - 9例:
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 演算子の概要: 論理、算術、ビット単位 - 10

Java の論理演算

それぞれの論理演算と真理値表を見てみましょう。
  • 否定演算 ( NOT);
  • 結合演算、論理 AND ( AND);
  • 論理和演算、論理 OR ( OR);
  • モジュロ加算演算、排他的論理和 ( XOR)。
否定演算子は単項であり、単一のオペランドに適用されます。他のすべての操作はバイナリです。これらの演算の真理値表を考えてみましょう。ここで、0は Java のfalseに相当し、1はtrueに相当します。
表 5. 否定演算子の真理値表 (NOT)
Java 演算子の概要: 論理、算術、ビット単位 - 7
表 6. 論理積演算子 (AND) の真理値表
Java 演算子の概要: 論理、算術、ビット単位 - 8
表 7. 論理和演算子 (OR) の真理値表
Java 演算子の概要: 論理、算術、ビット単位 - 9
表 8. モジュロ加算演算子 (XOR) の真理値表
Java 演算子の概要: 論理、算術、ビット単位 - 10Java にも同じ論理演算があります。
  • !— 否定演算子;
  • &&— 論理 AND 演算子 (短い)。
  • ||— 論理 OR 演算子 (短い)。
  • &— ビット単位の AND 演算子。
  • |— ビットごとの OR 演算子。
  • ^— ビットごとの排他的 OR 演算子。
以下でビット演算子と短縮演算子の違いを見てみましょう。また、すべての真理値表を Java コードに変換してみましょう。
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変数と一緒に使用することもできます。
Java 演算子の概要: 論理、算術、ビット単位 - 15
そしてboolean表現については次のようになります。
Java 演算子の概要: 論理、算術、ビット単位 - 16
ここで、短縮演算子 ( &&||) と同様のビット演算子 ( &|) を使用できます。それらの違いは何ですか? まず、ビット単位は整数に適用できます。これについては後ほど説明します。そして第二に、省略されるものもあれば、省略されないものもあります。略語がどのようなものかを理解するために、次の式を見てみましょう。

false AND x = ?
true OR x = ?
これにはx任意のブール値を指定できます。そして一般に、論理の法則と真理値表によれば、 truex falseかに関係なく、最初の式の結果はfalseになり、2 番目の式の結果はtrueになります。見て。
Java 演算子の概要: 論理、算術、ビット単位 - 17
場合によっては、式の結果が最初のオペランドから計算されることがあります。これが、省略された演算子&&と を区別するものです||。上記と同様の式では、2 番目のオペランドの値は評価されません。以下に小さな例を示します。
Java 演算子の概要: 論理、算術、ビット単位 - 18
短縮演算子の場合、式の 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 進数システムと同じ原理に従ってこれらの記号を組み合わせることで、無限に数を数えることができます。
10 進数と 2 進数で 0 から 15 までを数える例を示します。
Java 演算子の概要: 論理、算術、ビット単位 - 11ご覧のとおり、すべてはそれほど複雑ではありません。ビットに加えて、バイトキロバイトメガバイトギガバイトなどのよく知られた情報単位もあります。おそらく、1 バイトに 8 ビットがあることはご存知でしょう。それはどういう意味ですか?これは、連続する 8 ビットが 1 バイトを占めることを意味します。以下にバイトの例を示します。

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 つのタイプ番号はbyte256 の異なる値を取ることができます (負の値が 128、正の値が 127、ゼロが 1 つ)。各数値には、byte8 ビットの一意のセットがあります。byteこれは type だけでなく、すべての整数型に当てはまります。タイプはbyte最小のものを例として挙げています。以下の表は、すべての Java 整数型とそれらが占有するメモリ領域を示しています。 Java 演算子の概要: 論理、算術、ビット単位 - 12型について考えてみましょうint。2147483648 個の負の値、2147483647 個の正の値、および 1 つのゼロを保存できます。合計:

2147483648 + 2147483647 + 1 = 4294967296.
このタイプはコンピュータのメモリで 32 ビットを占有します。32 個の 0 と 1 のセットから可能な組み合わせの数は次のとおりです。
232 = 4294967296.
型が保持できる値の数と同じ数int。これは、データ型の値の範囲とそのサイズ (メモリ内のビット数) の関係を示す単なるデモンストレーションです。Java では任意の数の任意の型をバイナリに変換できます。Java 言語を使用してこれをいかに簡単に実行できるかを見てみましょう。type の例から学びますint。この型には独自のラッパー クラスがありますInteger。そして彼はtoBinaryString私たちのためにすべての作業を行ってくれる を持っています:
Java 演算子の概要: 論理、算術、ビット単位 - 21
ほら、それはそれほど複雑ではありません。しかし、それでも、何かを明確にする必要があります。intこの数値は 32 ビット必要です。ただし、上の例で数値 10 を出力すると、コンソールには 1010 と表示されますが、これは先頭のゼロが出力されないためです。これらが表示される場合、コンソールには 1010 の代わりに 00000000000000000000000000001010 が表示されますが、認識しやすくするために、先頭のゼロはすべて省略されています。「負の数はどうなるのでしょうか?」と自問するまでは、それほど難しいことではありません。二進法でのみ情報を認識します。マイナス記号もバイナリ コードで記述する必要があることがわかりました。これは、直接コードまたは補完コードを使用して実行できます。

ダイレクトコード

2 進数システムで数値を表現する方法。最上位ビット (左端のビット) が数値の符号に割り当てられます。数値が正の場合は左端のビットに 0 が書き込まれ、負の場合は - 1 が書き込まれます。
例として 8 ビット数値を使用してこれを見てみましょう。
Java 演算子の概要: 論理、算術、ビット単位 - 13このアプローチはシンプルで、原理的には理解できます。ただし、数学的演算の実行が難しいという欠点もあります。たとえば、負の数と正の数を加算します。追加の操作を実行しない限り、折りたたむことはできません。

追加コード

追加のコードを使用すると、直接コードの欠点を回避できます。数値の追加コードを取得する簡単なアルゴリズムがあります。数値 -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 進数に戻されます。演算のリストは次の表にあります。 Java 演算子の概要: 論理、算術、ビット単位 - 14すでにわかったように、数値はビットのセットとして表すことができます。ビット単位の演算は、そのような表現の各ビットに対して演算を実行します。NOT、、、、ANDを見てみましょうORXOR最近、論理オペランドのみの真理値表を調べたことを思い出してください。この場合、同じ演算が整数の各ビットに適用されます。

ビット単位の単項演算子 NOT ~

この演算子は、すべての 0 を 1 に置き換え、すべての 1 を 0 に置き換えます。10進法で10という数字があるとします。2 進数では、この数値は 1010 です。この数値に単項ビットごとの否定演算子を適用すると、次のような結果が得られます。 Java 演算子の概要: 論理、算術、ビット単位 - 15Java コードでどのように見えるかを見てみましょう。
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));
}
次に、コンソールに何が表示されるかを見てみましょう。
Java 演算子の概要: 論理、算術、ビット単位 - 25
最初の行では、先行ゼロなしの 2 進数システムで値を取得しています。私たちには見えなくても、彼らはそこにいます。これは、すべてのビットが逆ビットに変換された 2 行目で証明されています。これが、これほど多くの主要なユニットが見られる理由です。これらは、最初の行に出力されたときにコンパイラによって無視された、以前の先行ゼロです。以下は、わかりやすくするために先頭のゼロも表示する小さなプログラムです。
Java 演算子の概要: 論理、算術、ビット単位 - 26

ビット単位の AND 演算子

この演算子は 2 つの数値に適用されます。AND各数値のビット間の演算を実行します。例を見てみましょう。 Java 演算子の概要: 論理、算術、ビット単位 - 16この演算は 2 つの数値に対して実行されます。Java コードの例:
Java 演算子の概要: 論理、算術、ビット単位 - 28

ビット単位の OR 演算子

OR は 2 つの数値に適用されます。各数値のビット間で OR 演算を実行します。 Java 演算子の概要: 論理、算術、ビット単位 - 17これが IDEA でどのようになるかを見てみましょう。
Java 演算子の概要: 論理、算術、ビット単位 - 30

ビット演算、排他的論理和 (XOR)

同じ例を新しい操作で見てみましょう。 Java 演算子の概要: 論理、算術、ビット単位 - 18コード例:
Java 演算子の概要: 論理、算術、ビット単位 - 32

ビット単位で左シフト

この演算子は 2 つのオペランドに適用できます。つまり、演算ではx << y、数値のビットの位置が左にxシフトされます。yそれはどういう意味ですか?演算例を見てみましょう。10 << 1 Java 演算子の概要: 論理、算術、ビット単位 - 19演算結果は 10 進数の 20 になります。上の図からわかるように、すべてのビットが 1 だけ左にシフトされます。この操作中に、最上位ビット (左端のビット) の値が失われます。そして、最下位ビット (右端のビット) は 0 で埋められます。この作戦について何と言えますか?
  1. 数値のビットを左にビットずつシフトすることにより、数値をX2 N で乗算します。NX

    以下に例を示します。

    Java 演算子の概要: 論理、算術、ビット単位 - 34
  2. しかし!値 1 のビットが左端の位置にある場合、数値の符号が変わる可能性があります。

  3. 無限に左にシフトすると、数値は単純に 0 になります。ポイント 2 と 3 を見てみましょう。

    Java 演算子の概要: 論理、算術、ビット単位 - 35

ビット単位で右シフト

この演算子は 2 つのオペランドに適用されます。それらの。演算ではx >> y、数値のビットの位置が右にxシフトします。y別の例を見てみましょう。動作を概略的に分析してみましょう10 >> 1。数値 10 のすべてのビットを 1 つ右にシフトしてみましょう。 Java 演算子の概要: 論理、算術、ビット単位 - 20シフト操作中に、右のビットが失われます。それらはただ消えていきます。左端のビットは数値の符号です (0 は正、1 は負)。したがって、最終的な値には、元の数値と同じように配置されます。負の数値の例: Java 演算子の概要: 論理、算術、ビット単位 - 21右端のビットが失われ、左端のビットが数値の名誉符号として元の数値からコピーされます。IDEA でこれらすべてを行うにはどうすればよいでしょうか? 原則として、何も複雑なことはなく、単にそれを取得して移動するだけです。
Java 演算子の概要: 論理、算術、ビット単位 - 38
今。右にシフトした数字については何と言えますか? それらは 2 で割り切れます。右に 1 ビットシフトするたびに、元の数値を 2 で割ります。数値が 2 で割り切れない場合、結果はマイナス無限大に向かって丸められます (下位)。しかし、これはビットを 1 だけシフトする場合にのみ機能します。そして 2 ビットの場合は 4 で除算します。3 ビットの場合は 8 で除算します。4 ビットの場合は 16 で除算します。わかりますか? 2 のべき乗...数値をビット単位で右Xにシフトする場合N、数値をX2 の 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);
    }

   }

}
何が起きてる?
  1. 変数 i を 1 から 10 までインクリメントするループ。

  2. 反復ごとに 2 つの値を計算します。
    • shiftOperationResult数値 2048 を i ビット右にシフトした結果を変数に書き込みます。

    • devideOperationResult数値 2048 を 2 の i 乗で割った結果を変数に書き込みます。

  3. 取得した 2 つの値をペアで表示します。

プログラムの実行結果は次のようになります。 1024 - 1024 512 - 512 256 - 256 128 - 128 64 - 64 32 - 32 16 - 16 8 - 8 4 - 4 2 - 2

ゼロ埋め込みによるビット単位の右シフト

通常の右シフトは数値の符号を保持しますが (最上位ビットはその値を保持します)、ゼロ埋め右シフトは保持しません。そして、最上位ビットはゼロで埋められます。どのようなものかを見てみましょう: Java 演算子の概要: 論理、算術、ビット単位 - 22

Java での操作の優先順位

数学と同様、Java には演算の優先順位があります。以下の表は、検討した操作の優先順位 (最高から最低まで) を示しています。 Java 演算子の概要: 論理、算術、ビット単位 - 23

便利な使用例

数値のパリティを決定する

Java 演算子の概要: 論理、算術、ビット単位 - 24

配列内の最大要素を見つける

Java 演算子の概要: 論理、算術、ビット単位 - 25最小要素を見つけるには、適切な場所の比較記号を変更するだけです。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION