🐥

プログラミング自主学習 31日目 ビット論理演・移動演算子/代入演算子/条件演算子(三項演算子)/条演算の方向性と優先順位/SWITCH

2023/06/26に公開

ビット論理演算子

ビット論理演算子はbit単位で論理演算を行い、0と1が被演算子になるため、2進法を扱うbyte,short,int,longが被演算子にある。
主に通信業界で扱う演算で、メッセージのエラー、bit単位で解釈する際に使われる。

AND (&)

二つの二進法の数が1であれば、演算結果が1になる。その他は0だ。

0 0 1 0 1 1 0 1  = 45
      &
0 0 0 1 1 0 0 1  = 25

0 0 0 0 1 0 0 1  =9(結果)

OR(|)

二つの二進法の数の中で一つのビットが1であれば、演算結果が1になる。

0 0 1 0 1 1 0 1  = 45
      |
0 0 0 1 1 0 0 1  = 25

0 0 1 1 1 1 0 1  = 61 (結果)

XOR(^)

二つの二進法の数の中でいつのビットのみ1であれば、演算結果が1になる。その他は0だ。

0 0 1 0 1 1 0 1  = 45
      ^
0 0 0 1 1 0 0 1  = 25

0 0 1 1 0 1 0 1  = 52(結果)

NOT(~)

演算結果が逆になる。

0 0 1 0 1 1 0 1  = 45
      ~
1 1 0 1 0 0 1 0  = -46

変数の演算と同様、基本的にint型(32bit)に変換され、演算される。

C->java

Cには範囲が0~255であるuint8_tタイプのデーターがある。
こちらをjavaに変換するとこのような流れになる。

C 1 0 0 1 1 0 0 0 (136)  ---------------------->  java 1 0 0 1 1 0 0 0 (-120)

こちらにビット論理演算子を活用すると

byte recieveData = -120;
int unsignedInt = receiveData & 255

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 0 0 0
&
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 0

=136

本来の136に変換される。
このような方法もあるが、javaは Byte.toUnsignedInt() コードを提供する。

byte recieveData = -120;
int unsignedInt =Byte.toUnsignedInt(receiveData); //136
BitShiftExample
public class BitShiftExample {
	public static void main(String[] args) {
		int num1 = 1;
		int result1 = num1 << 3;
		int result2 = num1 * (int)Math.pow(2,3);
        System.out.println("result1 : "+ result1);
        System.out.println("result2 : "+ result2);
        
        int num2 = -8;
        int result3 = num2 >> 3;
		int result4 = num2 / (int)Math.pow(2, 3);
		System.out.println("result3 : "+ result3);
		System.out.println("result4 : "+ result4);
	}
}

ビット移動演算子

1.a << b 整数a左にbほど移動(a*2のb条、右のブランクは0になる)

1<<3 = 1*2^3 = 8 

2.a >> b 整数a右にbほど移動(a/2のb条、左のブランクはMSBと同じ値になる)

-8>>3 = -8/8 = -1

3. a >>> b 整数a右にbほど移動(左のブランクは0になる)

public class BitShiftExample2 {
public static void main(String[] args) {
    	int value = 772; //[00000000][00000000][00000011][00000100]
		
	//우측으로 3byte(24bit) 이동하고 끝 1바이트만 읽음: [00000000]
	byte byte1 = (byte)(value >>> 24);
	int int1 = byte1 & 255;
	System.out.println("첫 번째 바이트 부호 없는 값: " + int1);
		
	//우측으로 2byte(16bit) 이동하고 끝 1바이트만 읽음: [00000000]
	byte byte2 = (byte)(value >>> 16);
	int int2 = Byte.toUnsignedInt(byte2);
	System.out.println("두 번째 바이트 부호 없는 값: "+ int2);
		
	//우측으로 1byte(8bit) 이동하고 끝 1바이트만 읽음: [00000011]
	byte byte3 = (byte)(value >>> 8);
	int int3 = byte3 & 255;
	System.out.println("세 번째 바이트 부호 없는 값: " + int3);
		
	//끝 1byte만 읽음: [00001000]
	byte byte4 = (byte)(value);
	int int4 = Byte.toUnsignedInt(byte4);
	System.out.println("네 번째 바이트 부호 없는 값: " + int4);
	}
}

重要複合代入演算子

変数+=被演算子 :変数の値に被演算子の値を足した後、変数に代入する。
変数-=被演算子 :変数の値に被演算子の値を引いた後、変数に代入する。
変数*=被演算子 :変数の値に被演算子の値をかけた後、変数に代入する。
変数/=被演算子 :変数の値に被演算子の値を割った後、変数に代入する。
変数%=被演算子 :変数の値に被演算子の値を割った後のあまり、変数に代入する。

等号の前にある算出演算子・ビット演算子により結果値が異なる。

public class AssignmentOperatorExample {
	public static void main(String[] args) {
		int result = 0;
		result +=10;
		System.out.println("result = " + result);
		result -=5;
		System.out.println("result = " + result);
		result *=3;
		System.out.println("result = " + result);
		result /=5;
		System.out.println("result = " + result);
		result %=3;
		System.out.println("result = " + result);
	}
}

条件演算子(三項演算子)

return = (条件式)? trueの場合returnする値 : falseの場合returnする値

package ch03.sec11;

public class ConditionalOperationExample {

public static void main(String[] args) {
	int score = 85;
        char grade = (score>90) ? 'A':(score>80? 'B':'C');
	System.out.println(score + "점은 " +grade +"등급입니다.");
    }
}
<result>
85점은 B등급입니다.

条演算の方向性と優先順位

代入演算子や単項演算子(符号、増減)、~、!演算子は演算方向が逆だ。

a=b=c=5;
c=5 -> b=c -> a=b 

優先順位

無()>単項演算子(符号、増減[++,--]、!、~)>算術 > 比較 > 論理> 代入

public class OperatorPriority {
   public static void main(String[] args) {
   	int a=1;
	int b=2;

	int result1 = a--*b;  
	int result2 = a*b;
	int result3 = ++a*b;
	int result4 = -a*b;
	boolean result5 = !(a>b);

	System.out.println("result1: "+ result1);
	System.out.println("result2: "+ result2);
	System.out.println("result3: "+ result3);
	System.out.println("result4: "+ result4);
	System.out.println("result5: "+ result5);
	}
}
	

SWITCH

1. switch(変数){case 変数: 命令文 ; break; } ;が一般的なケースだ。

変数のケースをはっきり把握できる際に使えば、else if より綺麗にコードをまとめることができる。最後のelseはdefault: 命令文が付く。breakはいらない。

2. switch(変数)には実数(float,double)は代入できない。

3.breakなしで、綺麗にまとめることもできる。

<単一値>

char grade = 'b'

switch(grade) {
case 'a'"A" -> {System.out.println("優秀会員です。")}
case 'b''B'  -> {System.out.println("一般会員です。")}
default       -> {System.out.println("ゲストです。")}
}
switch(grade) {
case 'a'"A" -> System.out.println("優秀会員です。")
case 'b''B'  -> System.out.println("一般会員です。")
default       -> System.out.println("ゲストです。")
}

中括弧の活用

単一値の場合はー>で値を代入することができ、
中格好を活用する際にはyieldを使用して値を代入することができる。
その場合はdefault; が必須になり、switchの}に;を付ける。


int grade ='b';

int score = switch(grade){
    case "A"->100;
    case "B" -> {
        int result = 100-20;
        yield result;
     }
   default -> 60;
};

System.out.println(score)

Discussion