プログラミングにおける式（Expression）は、値や演算子、関数呼び出し、変数などから構成される計算を表す文法構造です。式はプログラム内で評価され、結果の値を生成します。
演算子（Operator）は、式内で値や変数を操作するための記号またはキーワードです。演算子には算術演算子（加算、減算など）、比較演算子（等しい、大なり、小なりなど）、論理演算子（AND、ORなど）、代入演算子（変数に値を代入する演算子）などがあります。演算子は一般的に、式内で値を組み合わせて新しい値を生成するために使用されます。
例えば、以下のような式があります:
a + b * c
この式は、変数 a、b、c の値を使用して、乗算(*)と加算(+)の演算を行います。これにより、新しい値が生成されます。
Javaにおける式（Expression）は、値、変数、演算子、メソッド呼び出し、またはこれらの組み合わせから構成されるプログラム内の計算を表す文法要素です。式はプログラム内で評価され、結果の値を生成します。
Javaの演算子（Operator）は、式内で値や変数を操作するための特殊な記号またはキーワードです。
Javaの演算子は多岐にわたり、主な種類には以下のようなものがあります：
算術演算子（Arithmetic Operators）: 加算（+）、減算（-）、乗算（*）、除算（/）、剰余（%）など、数値データ型の間で算術演算を実行するための演算子です。
比較演算子（Comparison Operators）: 等しい（==）、等しくない（!=）、大なり（>）、小なり（<）、大なりイコール（>=）、小なりイコール（<=）など、値や式の比較を行うための演算子です。結果は真偽値（trueまたはfalse）となります。
論理演算子（Logical Operators）: 論理積（AND：&&）、論理和（OR：||）、否定（NOT：!）など、真偽値を操作するための演算子です。
ビット演算子（Bitwise operators）: 論理積（AND：&）、論理和（OR：|）、排他的論理和（XOR：^）、否定（NOT：~）などの操作を提供し、ビット単位の操作により効率的なデータ処理やビットマスクの作成が可能です。
代入演算子（Assignment Operators）: 代入（=）、加算代入（+=）、減算代入（-=）、乗算代入（*=）など、変数に値を代入するための演算子です。
その他の演算子（Other Operators）: インクリメント（++）、デクリメント（--）、条件演算子（条件式 ? 結果1 : 結果2）、ビット演算子（ビット単位の論理演算を行う演算子）など、その他の種類の演算子があります。
これらの演算子を使用して、Javaプログラム内で様々な計算や操作を行うことができます。
Javaにおける算術演算子は、基本的な数値計算を行うための演算子を指します。
Javaでは、整数型と浮動小数点型のデータを扱うための算術演算子が提供されています。
主な算術演算子には以下が含まれます：
int sum1 = 5 + 3; // 整数の加算、sum1には8が代入される
double sum2 = 5.5 + 3.2; // 浮動小数点数の加算、sum2には8.7が代入される
int difference1 = 10 - 4; // 整数の減算、difference1には6が代入される
double difference2 = 10.5 - 4.2; // 浮動小数点数の減算、difference2には6.3が代入される
int product1 = 6 * 2; // 整数の乗算、product1には12が代入される
double product2 = 3.5 * 2.0; // 浮動小数点数の乗算、product2には7.0が代入される
double quotient1 = 10.0 / 3.0; // 浮動小数点数の除算、quotient1には3.3333...が代入される
double quotient2 = 10 / 3.0; // 整数と浮動小数点数の除算、quotient2には3.3333...が代入される
int remainder1 = 10 % 3; // 整数の剰余、remainder1には1が代入される
double remainder2 = 10.5 % 3.0; // 浮動小数点数の剰余、remainder2には1.5が代入される
Javaの算術演算は、整数型と浮動小数点型の両方で動作し、適切な結果を返します。
プログラマは、演算に使用される数値の型を適切に選択する必要があります。
/**
 * 算術演算子の例
 */
public class Main {
    /**
     * メインメソッド。プログラムのエントリーポイント。
     * 
     * @param args コマンドライン引数
     */
    public static void main(String[] args) {
        int a = 10;
        int b = 3;
        
        System.out.println(a + " + " + b + " = " + (a + b));
        System.out.println(a + " - " + b + " = " + (a - b));
        System.out.println(a + " * " + b + " = " + (a * b));
        System.out.println(a + " / " + b + " = " + (a / b));
        System.out.println(a + " % " + b + " = " + (a % b));
        a = Integer.MAX_VALUE;
        b = 1;
        System.out.println(a + " + " + b + " = " + (a + b) + "\t// オーバーフロー！");
        // ゼロ除算:
        a = 42;
        b = 0;
        try {
            System.out.print(a + " / " + b + " = ");
            System.out.println(a / b);
        } catch (ArithmeticException e) {
            System.out.println("例外捕捉:" + e);
        }
        
        // ゼロ除算:
        try {
            System.out.print(a + " % " + b + " = ");
            System.out.println(a % b);
        } catch (ArithmeticException e) {
            System.out.println("例外捕捉:" + e);
        }
        
        // double型の算術演算
        double x = 10.5;
        double y = 3.2;
        System.out.println(x + " + " + y + " = " + (x + y));
        System.out.println(x + " - " + y + " = " + (x - y));
        System.out.println(x + " * " + y + " = " + (x * y));
        System.out.println(x + " / " + y + " = " + (x / y));
        System.out.println(x + " % " + y + " = " + (x % y));
        y = 0.0;
        System.out.println(x + " / " + y + " = " + (x / y));
        x = 0.0;
        System.out.println(x + " / " + y + " = " + (x / y));
    }
}
実行結果:
10 + 3 = 13
10 - 3 = 7
10 * 3 = 30
10 / 3 = 3
10 % 3 = 1
2147483647 + 1 = -2147483648	// オーバーフロー！
42 / 0 = 例外捕捉:java.lang.ArithmeticException: / by zero
42 % 0 = 例外捕捉:java.lang.ArithmeticException: / by zero
10.5 + 3.2 = 13.7
10.5 - 3.2 = 7.3
10.5 * 3.2 = 33.6
10.5 / 3.2 = 3.28125
10.5 % 3.2 = 0.8999999999999995
10.5 / 0.0 = Infinity 
0.0 / 0.0 = NaN
JavaのInfinityとNaNは、浮動小数点数の特殊な値であり、IEEE 754規格に基づいて定義されています。以下に、それぞれの意味と特性について説明します。
JavaのInfinityとNaNは、浮動小数点数の計算において特殊な値として使用されます。これらの値は、次のような場面で発生します。
無限大は、有限の数値を0.0で割った場合や、オーバーフローが発生した場合に発生します。
例えば、double result = 5.0 / 0.0;のような式を評価すると、resultの値は無限大になります。
無限大は、有限の数値よりも大きいことが特性として挙げられます。
Double.POSITIVE_INFINITYの定数は（正の）無限大を表します。
IEEE 754規格では、無限大は指数部が符号が+、最大値でかつ仮数部が0の状態で表されます。
負の無限大、有限の負の数値を0.0で割った場合や、オーバーフローが発生した場合に発生します。
例えば、double result = 5.0 / -0.0;のような式を評価すると、resultの値は負の無限大になります。
負の無限大は、有限の数値よりも小さいことが特性として挙げられます。
Double.NEGATIVE_INFINITYの定数は、負の無限大を表します。
IEEE 754規格では、負の無限大は指数部が符号が+、最大値でかつ仮数部が0の状態で表されます。
NaNは、0を0で割った場合や、0.0を0.0で割った場合、あるいは数学的に不正な演算が行われた場合に発生します。
例えば、double result = Math.sqrt(-1);のような式を評価すると、resultの値はNaNになります。
NaNは、数値としての意味を持たないことを示します。
Double.NaNという定数があり、これはNaNを表します。
NaNは、どの数値とも等しくないため、NaNとの比較は常にfalseになります。
IEEE 754規格では、NaNは指数部が最大値でかつ仮数部が0でない状態で表されます。
isNaN()とisFinite()メソッド:
Javaでは、DoubleクラスやFloatクラスには、NaNやInfinityを判定するためのメソッドが用意されています。
isNaN()メソッドは、引数がNaNかどうかを判定します。NaNの場合はtrueを返し、それ以外の場合はfalseを返します。
isFinite()メソッドは、引数が有限の数かどうかを判定します。InfinityやNaNの場合はfalseを返し、それ以外の場合はtrueを返します。
IEEE 754規格に基づいて定義されたこれらの特殊な値は、浮動小数点数の算術演算においてエラー処理や特殊な状況を処理するために使用されます。これらの特性を理解することは、正確な数値計算を行う上で重要です。
-0.0（マイナスゼロ）は、浮動小数点数の一部で、通常のゼロとは異なる概念です。IEEE 754規格では、ゼロを表現する方法として、符号付きゼロ（+0.0および-0.0）が導入されています。
+0.0（プラスゼロ）: すべてのビットが0で、符号ビットが0。
-0.0（マイナスゼロ）: すべてのビットが0で、符号ビットが1。
この区別は、通常の算術演算では影響を与えませんが、一部の特殊な状況で重要になります。例えば、次のような場面で符号つきゼロが役立ちます。
1.0 / +0.0 は正の無限大になります。
1.0 / -0.0 は負の無限大になります。
符号つきゼロは、正確な結果を保持するために使用されます。例えば、正の数から負の数を引くときなどに、結果の符号を正確に反映するために使われます。
JavaのDoubleとFloatのデータ型では、+0.0と-0.0は異なる値として区別されます。これは、JavaがIEEE 754規格に従っているためです。例えば、以下のようなコードを実行すると、+0.0と-0.0が等しいかどうかを確認できます。
System.out.println(0.0 == -0.0); // true
System.out.println(Double.compare(0.0, -0.0)); // 1
System.out.println(Double.compare(0.0, 0.0)); // 0
System.out.println(Double.compare(-0.0, 0.0)); // -1
 
このコードでは、==演算子によって0.0と-0.0が等しいかどうかを比較しています。
Double.compareメソッドによって比較すると、ゼロの符号の違いを考慮します。
Double.compare() は、Java プログラミング言語において、2 つの double 値を比較するための静的メソッドです。このメソッドは、次のような形式で使用されます：
public static int compare(double d1, double d2)
Double.compare() メソッドは、以下のルールに従って比較を行います。
もし d1 が d2 より小さい場合、負の値が返されます。
もし d1 が d2 より大きい場合、正の値が返されます。
もし d1 が d2 と等しい場合、0 が返されます。
整数演算の桁あふれ（オーバーフロー）は、整数の演算結果がそのデータ型で表現可能な範囲を超える場合に発生します。Javaの整数型には、それぞれの範囲が定義されています。以下に、主な整数型とその範囲を示します。
たとえば、int型でのオーバーフローが発生する状況を考えてみましょう。以下のコードでは、整数の最大値に1を加えようとしています。
 
int maxValue = Integer.MAX_VALUE;
int overflow = maxValue + 1;
System.out.println("Overflow: " + overflow);
このコードを実行すると、overflow 変数は -2147483648 になります。これは、Integer.MAX_VALUE で表現される最大値に1を加えることで、オーバーフローが発生し、最小値（Integer.MIN_VALUE）に戻るためです。
同様に、他の整数型でも同様の挙動が発生します。オーバーフローを防ぐためには、適切な範囲内での演算を行うか、オーバーフローが発生する可能性がある場合には適切に処理する必要があります。
Javaでは、整数演算でオーバーフローを生じても例外は上がりません。
例外をあげオーバーフローを捕捉するために、Math.addExactと、そのファミリーが用意されています。
Math.addExact() メソッドは、Java 8 で追加された整数演算時のオーバーフローを検出するためのメソッドの一部です。このメソッドは、整数型の加算を行い、結果がそのデータ型で表現可能な範囲を超えた場合に ArithmeticException をスローします。
Math クラスには、他にもオーバーフローを検出するためのメソッドが用意されています。主なものには、次のようなものがあります：
Math.addExact(int x, int y)：整数値 x と y を加算し、オーバーフローが発生した場合は ArithmeticException をスローします。
Math.subtractExact(int x, int y)：整数値 x から y を減算し、オーバーフローが発生した場合は ArithmeticException をスローします。
Math.multiplyExact(int x, int y)：整数値 x と y を乗算し、オーバーフローが発生した場合は ArithmeticException をスローします。
Math.incrementExact(int a)：整数値 a をインクリメントし、オーバーフローが発生した場合は ArithmeticException をスローします。
Math.decrementExact(int a)：整数値 a をデクリメントし、オーバーフローが発生した場合は ArithmeticException をスローします。
これらのメソッドを使用することで、整数演算時にオーバーフローが発生した場合に、適切に例外を処理できます。
以下は、Math.addExact() メソッドを使用して整数値の加算を行い、オーバーフローが発生した場合に例外を処理する例です。
public class Main {
    public static void main(String[] args) {
        try {
            int result = Math.addExact(Integer.MAX_VALUE, 1);
            System.out.println("Result: " + result);
        } catch (ArithmeticException e) {
            System.out.println("Overflow occurred: " + e.getMessage());
        }
    }
}
 
このコードでは、Integer.MAX_VALUE に 1 を加算しようとしています。Math.addExact() メソッドは、この加算がオーバーフローを引き起こす可能性があるため、例外をスローします。try-catch ブロックを使用して、ArithmeticException をキャッチし、オーバーフローが発生したことを示すメッセージを出力しています。
浮動小数点演算の桁あふれは、浮動小数点数を操作する際に、その値がデータ型で表現可能な範囲を超える場合に発生します。浮動小数点数は、指数部と仮数部から構成され、一定の精度を保ちつつ非常に大きな値や小さな値を表現するために使用されます。
Javaにおいて、浮動小数点数は主に以下の2つのデータ型で表現されます。
これらのデータ型は、それぞれ一定の範囲と精度を持っていますが、非常に大きな値や小さな値に対しても表現可能です。
桁あふれは、浮動小数点演算の結果が、そのデータ型で表現可能な範囲を超える場合に発生します。これにより、計算結果が無限大や無限小に発散する場合や、精度が失われる場合があります。また、浮動小数点数の演算において、有効桁数を超えた部分が切り捨てられることも桁あふれの一形態です。
例えば、次のコードでは、倍精度浮動小数点数の最大値に1を加える操作を行っています。
 
double maxValue = Double.MAX_VALUE;
double overflow = maxValue + 1;
System.out.println("Overflow: " + overflow);
この場合、overflow 変数の値は Infinity になります。これは、最大値に1を加えた結果が倍精度浮動小数点数の表現可能な範囲を超えたため、桁あふれが発生したことを示しています。
Javaの浮動小数点数における誤差は、主に2つの要因によって生じます。
有効桁数の制限: Javaの浮動小数点数は、IEEE 754標準に基づいて実装されています。float型は32ビットで、有効桁数は約7桁です。double型は64ビットで、有効桁数は約15桁です。そのため、非常に大きな数や非常に小さな数を表現する場合、精度の制限により誤差が生じます。たとえば、10進数で0.1をfloat型やdouble型で表現すると、厳密には0.1ではなく、近似的な値になります。
丸め誤差と演算誤差: 浮動小数点数の演算においては、丸め誤差や演算誤差が生じることがあります。これは、浮動小数点数を近似的に表現するための有限なビット数で演算を行うために生じるものです。特に、加算や減算、乗算、除算などの演算において、丸め誤差や演算誤差が生じることがあります。これにより、計算結果が厳密な値と異なる場合があります。
Javaの浮動小数点数における誤差を最小限に抑えるためには、次のような注意点があります。
計算の順序を適切に管理し、丸め誤差を最小限に抑える。
必要に応じて、BigDecimalクラスを使用して高精度な計算を行う。
数値計算ライブラリや専門家によって提供される特殊な数値計算手法を使用する。
これらの対策を講じることで、Javaの浮動小数点数による誤差を最小限に抑えることができます。
また、浮動小数点数の演算における丸め誤差や演算誤差を最小限に抑えるためには、以下のような注意点があります。
適切なデータ型を選択する: 浮動小数点数は精度を失う可能性があるため、必要な精度に合わせてfloat型またはdouble型を選択する必要があります。より高い精度が必要な場合はdouble型を使用しますが、その分メモリ使用量も大きくなります。
演算の順序を考慮する: 浮動小数点数の演算においては、演算の順序が結果に影響を与える場合があります。たとえば、加算や減算といった基本的な演算から始め、乗算や除算といった複雑な演算を後に行うと、丸め誤差を最小限に抑えることができます。
比較演算における注意: 浮動小数点数の比較演算は、厳密な等値判定が難しい場合があります。丸め誤差や演算誤差の影響を考慮して、適切な精度で比較演算を行う必要があります。通常は、等値判定ではなく、ある値が別の値よりも大きいか、または小さいかを判定することが推奨されます。
結果の解釈: 浮動小数点数の演算結果を解釈する際には、その精度や誤差の範囲を理解する必要があります。特に、科学計算や金融取引などの精密な計算においては、計算結果の信頼性を確保するために十分な検証と解釈が必要です。
これらの注意点を考慮することで、Javaの浮動小数点数による計算における誤差を最小限に抑えることができます。
さらに、浮動小数点数の計算における誤差を最小限に抑えるために、次のようなアプローチも考慮されます。
丸めモードの設定: Javaでは、浮動小数点数の計算における丸めモードを設定することができます。デフォルトでは、丸めモードは「デフォルト」であり、周囲に最も近い数に丸められます。しかし、必要に応じて丸めモードを変更して、計算結果に影響を与えることができます。例えば、丸め誤差を最小限に抑えるために、上向き丸め（ceiling）、下向き丸め（floor）、ゼロから遠い方向の丸め（向上丸め）、ゼロに近い方向の丸め（向下丸め）などの丸めモードを使用することができます。
有効桁数の管理: 浮動小数点数の計算においては、有効桁数の制限により誤差が生じることがあります。特に、非常に大きな数や非常に小さな数を表現する場合、有効桁数の不足により計算結果に誤差が生じることがあります。そのため、計算に使用する浮動小数点数の有効桁数を適切に管理することが重要です。必要に応じて、BigDecimalなどの精度の高いデータ型を使用して計算を行うことも考慮されます。
ライブラリの活用: 数値計算に関連するライブラリを活用することで、浮動小数点数の計算における誤差を最小限に抑えることができます。これらのライブラリには、高精度な計算を行うための機能や、誤差を最小限に抑えるためのアルゴリズムが含まれています。特に、金融取引や科学計算などの精密な計算を行う場合には、これらのライブラリを活用することが推奨されます。
以上のようなアプローチを組み合わせることで、Javaの浮動小数点数を使用した計算における誤差を最小限に抑えることができます。ただし、特定の問題や要件に応じて、最適なアプローチを選択する必要があります。
浮動小数点数の内部表現により、一部の10進数を正確に表現することができません。たとえば、0.1を浮動小数点数として表現すると、厳密な値ではなく近似値になります。そのため、0.1を10回足しても厳密に1.0にはならない場合があります。
Javaでは、float型やdouble型を使用して浮動小数点数を表現しますが、これらの型は有限のビット数で浮動小数点数を表現するため、一部の10進数を正確に表現することができません。その結果、浮動小数点数の計算においては、丸め誤差や演算誤差が生じる可能性があります。
例えば、次のコードを見てみましょう。
double sum = 0.0;
for (int i = 0; i < 10; i++) {
    sum += 0.1;
}
System.out.println(sum); // 出力: 0.9999999999999999
 
このコードでは、0.1を10回足した結果が正確に1.0にならず、0.9999999999999999 という近似値になります。
このように誤差が生じるのは、内部的に浮動小数点数は2進数で扱われているためです（0.1は、2進数では循環小数になるため正確に表現できません）。
誤差を補正する方法はいくつかありますが、カハンの総和アルゴリズム( ''Kahan summation algorithm'' )が代表的です。
[https://paiza.io/projects/gMFZzp8gUybEJfpUSuWH9A?language=java カハンの総和アルゴリズム]:
public class Main {
    public static void main(String[] args) {
        double d = 0.0;
        for (int i = 0; i < 10; i++) d += 0.1;
        System.out.println(d);
        d = 0.0;
        double c = 0.0;
        for (int i = 0; i < 10; i++) {
            double y = 0.1 - c;
            double t = d + y;
            c = ( t - d ) - y;
            d = t;
        }
        System.out.println(d);
        float f = 0.0f;
        for (int i = 0; i < 10; i++) f += 0.1f;
        System.out.println(f);
        
        f = 0.0f;
        float fc = 0.0f;
        for (int i = 0; i < 10; i++) {
            float y = 0.1f - fc;
            float t = f + y;
            fc = ( t - f ) - y;
            f = t;
        }
        System.out.println(f);
    }
}
$ javac Main.java
$ java Main
0.9999999999999999
1.0
1.0000001 
1.0
また、Java Stream API も補正アルゴリズムを実装しています。
[https://paiza.io/projects/gDqEBXyDFiPI3gDfuxGbZg?language=java Stream APIを使った総和]:
import java.util.stream.DoubleStream;
class Main {
    public static void main(String[] args) {
        // DoubleStream.builder() を使用して、DoubleStream.Builderオブジェクトを作成します。
        // これは、DoubleStreamを構築するためのビルダーオブジェクトです。
        final var builder = DoubleStream.builder();
        
        // ループを10回実行し、builder.add(0.1) を使用して、ビルダーオブジェクトに0.1を追加します。
        // これにより、10回のループを通じて0.1が10回追加されます。
        for (int i = 0; i < 10; i++)
            builder.add(0.1);
        
        // builder.build() を使用して、ビルダーオブジェクトからDoubleStreamオブジェクトを構築します。
        // これにより、10回のループで追加された0.1の値が含まれたDoubleStreamが得られます。
        System.out.println(builder.build().sum());
        
        // sum() メソッドを使用して、DoubleStreamオブジェクトの合計を計算します。
        // これにより、10回のループで追加された0.1の値の合計が計算されます。
        
        // 最後に、計算された合計値が出力されます。
    }
}
1.0
DoubleStreamのメソッドsum()は、保証を行うアルゴリズムを採用しています。
Javaの算術演算子には、優先順位と結合性があります。以下に、一般的な算術演算子の優先順位と結合性を示します。
乗算 (*) および除算 (/、%): 乗算と除算は、加算と減算よりも高い優先順位を持ちます。また、乗算と除算は左から右に結合します。
加算 (+) および減算 (-): 加算と減算は、乗算と除算と同じ優先順位を持ちます。また、加算と減算も左から右に結合します。
この優先順位と結合性に基づいて、式が評価されます。例えば、次の式を考えてみましょう。
int result = 5 + 3 * 2;
この式では、乗算 (*) が加算 (+) よりも高い優先順位を持つため、まず 3 * 2 が計算されます。結果は 6 です。その後、5 と 6 の加算が行われ、最終的な結果は 11 になります。
結合性（associativity）は、演算子が式内で連続して出現する場合に、その演算子がどのような順序で評価されるかを示す性質です。結合性は通常、左から右への結合（左結合性）または右から左への結合（右結合性）のいずれかとして定義されます。
算術演算子の結合性により、この式は左から右に評価されます。例えば、次の式を考えてみましょう。
int result = 10 - 5 - 3;
この式では、減算 (-) は左から右に結合するため、まず左側の 10 - 5 が計算されます。結果は 5 です。その後、5 から 3 を減算することで、最終的な結果は 2 になります。
Javaの算術演算子の優先順位と結合性を理解することで、式を正しく評価することができます。
Javaの比較演算子は、異なる値や式の間で比較を行い、結果を真偽値（trueまたはfalse）で返します。以下は、Javaで使用される主な比較演算子です。
==：2つの値が等しいかどうかを比較します。プリミティブ型の場合、値の比較を行います。参照型の場合、オブジェクトの参照が同じかどうかを比較します。
!=：2つの値が等しくないかどうかを比較します。
>：左辺の値が右辺の値より大きいかどうかを比較します。
<：左辺の値が右辺の値より小さいかどうかを比較します。
>=：左辺の値が右辺の値以上かどうかを比較します。
<=：左辺の値が右辺の値以下かどうかを比較します。
これらの比較演算子は、条件文やループ、その他の制御構造でよく使用されます。
論理演算子は、論理値（真偽値）を操作するために使用されます。Javaでは、3つの主要な論理演算子があります。
&&（AND）：論理積演算子は、両側の式がともにtrueの場合にtrueを返します。片方でもfalseであれば、falseを返します。
||（OR）：論理和演算子は、両側の式の少なくとも一方がtrueの場合にtrueを返します。両方がfalseの場合にfalseを返します。
!（NOT）：論理否定演算子は、式の真偽を反転させます。trueはfalseに、falseはtrueになります。
これらの演算子は、条件文やループなどの制御構造で論理式を組み立てるために使用されます。
ビット演算子は、整数のビットレベルでの演算を実行します。Javaのビット演算子は、以下のようになります。
&：ビット単位のAND演算を行います。
|：ビット単位のOR演算を行います。
^：ビット単位のXOR（排他的論理和）演算を行います。
~：ビット単位の補数（ビット反転）演算を行います。
<<：左シフト演算子は、ビットを左に指定された数だけシフトします。
>>：符号付き右シフト演算子は、ビットを右に指定された数だけシフトします。符号ビットは左端のビット（MSB）にコピーされます。
>>>：符号なし右シフト演算子は、ビットを右に指定された数だけシフトします。左端のビットは0になります。
これらの演算子は、ビット単位のデータ処理や、効率的なビットマスクの作成に使用されます。
代入演算子は、変数に値を割り当てるために使用されます。Javaの代入演算子には、単純な代入演算子と複合代入演算子があります。
=：単純な代入演算子は、右辺の値を左辺の変数に代入します。
+=：加算代入演算子は、左辺の変数に右辺の値を加算し、結果を左辺の変数に代入します。
-=：減算代入演算子は、左辺の変数から右辺の値を減算し、結果を左辺の変数に代入します。
*=：乗算代入演算子は、左辺の変数に右辺の値を乗算し、結果を左辺の変数に代入します。
/=：除算代入演算子は、左辺の変数を右辺の値で除算し、結果を左辺の変数に代入します。
%=：剰余代入演算子は、左辺の変数を右辺の値で剰余計算し、結果を左辺の変数に代入します。
これらの演算子は、変数の値を更新する際に使用され、簡潔なコードを記述するのに役立ちます。
----
式と演算子
public class Main {
    public static void main(String[] args) {
        int x = 5;
        int y = 3;
        
        // 算術演算子
        int sum = x + y; // 加算
        int difference = x - y; // 減算
        int product = x * y; // 乗算
        int quotient = x / y; // 除算
        int remainder = x % y; // 剰余
        
        // 比較演算子
        boolean isEqual = x == y; // xとyが等しいかどうか
        boolean isNotEqual = x != y; // xとyが等しくないかどうか
        boolean isGreaterThan = x > y; // xがyより大きいかどうか
        boolean isLessThan = x < y; // xがyより小さいかどうか
        boolean isGreaterOrEqual = x >= y; // xがy以上かどうか
        boolean isLessOrEqual = x <= y; // xがy以下かどうか
        
        // 論理演算子
        boolean andResult = (x > 0) && (y < 0); // 論理積（AND）
        boolean orResult = (x > 0) || (y < 0); // 論理和（OR）
        boolean notResult = !(x > 0); // 論理否定（NOT）
        
        // ビット演算子
        int bitAnd = x & y; // ビット単位のAND
        int bitOr = x | y; // ビット単位のOR
        int bitXor = x ^ y; // ビット単位のXOR
        int bitComplementX = ~x; // ビット単位の補数
        int leftShift = x << 1; // 左シフト
        int rightShift = x >> 1; // 右シフト
        
        // 代入演算子
        int a = 10;
        a += 5; // a = a + 5
        int b = 20;
        b -= 3; // b = b - 3
    }
}
このJavaプログラムでは、算術演算子、比較演算子、論理演算子、ビット演算子、代入演算子が使用されています。コメント中には各演算子の説明が含まれており、それぞれの演算子が何を行うかが明確に示されています。
式 (Expression): プログラミングにおいて、値、演算子、変数、関数呼び出しなどから構成される計算を表す文法構造。プログラム内で評価され、結果の値を生成する。
演算子 (Operator): 式内で値や変数を操作するための記号やキーワード。算術演算子、比較演算子、論理演算子、ビット演算子、代入演算子などがある。
算術演算子 (Arithmetic Operators): 加算、減算、乗算、除算、剰余など、数値データ型の間で算術演算を実行するための演算子。
比較演算子 (Comparison Operators): 等しい、等しくない、大なり、小なりなど、値や式の比較を行う演算子。
論理演算子 (Logical Operators): 論理積 (AND)、論理和 (OR)、否定 (NOT) など、真偽値を操作するための演算子。
ビット演算子 (Bitwise Operators): 論理積、論理和、排他的論理和、否定など、ビット単位の操作に使用される演算子。
代入演算子 (Assignment Operators): 代入、加算代入、減算代入、乗算代入など、変数に値を代入する演算子。
加算 (Addition): +。整数や浮動小数点数の加算。
減算 (Subtraction): -。整数や浮動小数点数の減算。
乗算 (Multiplication): *。整数や浮動小数点数の乗算。
除算 (Division): /。浮動小数点数の除算。整数と浮動小数点数の場合もあり。
剰余 (Modulus): %。整数や浮動小数点数の剰余。
Javaで異なるデータ型での算術演算子の使用例。
Infinity (無限大): 有限の数値を0.0で割った場合やオーバーフローが発生した場合に発生。Double.POSITIVE_INFINITYで表現される。
-Infinity (負の無限大): 有限の負の数値を0.0で割った場合やオーバーフローが発生した場合に発生。Double.NEGATIVE_INFINITYで表現される。
NaN (非数): 0を0で割った場合や不正な演算が行われた場合に発生。Double.NaNで表現され、数値としての意味を持たないことを示す。