論理演算

ビット演算

ビッド演算とは、各bitに対して論理演算を行うことを指します。なお、特にシフト演算では、変数はunsigned、または正の整数である必要があります。負の数の場合動作は実装定義となります。

まあ、そもそもsignedな整数にビット演算をするべきではありません。

左シフト

const uint8_t fit = 5 << 4;//80:1010000
const uint8_t over = 5 << 30;//64:01000000

左シフトではnビット分ビットがずれる。下nビットは0になり, 元の値の上nビットは無視される。

オーバーフローしない限り、1つ左シフトするごとに、2をかけているのと同じ効果が得られる。この場合は24 = 16倍していることになる。

可読性が下がるので乗算の代わりに用いない。確かにシフト演算のほうが高速だが、そのような最適化はコンパイラがやってくれる。

右シフト

uint32_t si_a = 37;//100101
const uint32_t si_b = 4;
const uint32_t re_si = si_a >> si_b;//2:10

右シフトには算術シフトと論理シフトの2種類がある。論理シフトでの右シフトは左シフトの逆になるだけだが、算術シフトでは元の値の最上位ビットが維持される。
多くの処理系では論理シフトだが、算術シフトのものもあるので注意すること。

処理系依存があるので、左シフト以上に除算の代わりに用いることは避ける。

ビットの論理積

const uint32_t a = 0b10110;//22
const uint32_t b = 0b11010;//26
const uint32_t re = a & b;//18:0b10010

各ビットの論理積を取ります。

AND
A B A & B
0 0 0
0 1 0
1 0 0
1 1 1

結果はこの表に従います。

問題

下記は、論理積を用いて整数型が偶数か奇数かを判断し、偶数なら0,奇数なら1を表示するプログラムである。完成させよ。

#include <stdio.h>

int main()
{
	const unsigned int target = 11235;
	const unsigned int isOdd = ;

	printf("%d\n", isOdd);
	return 0;
}

ビットの論理和

const uint32_t a = 0b10110;//22
const uint32_t b = 0b11010;//26
const uint32_t re = a | b;//30:0b11110

各ビットの論理和を取ります。

OR
A B A | B
0 0 0
0 1 1
1 0 1
1 1 1

結果はこの表に従います。

ビットの排他論理和

const uint32_t a = 0b10110;//22
const uint32_t b = 0b11010;//26
const uint32_t re = a ^ b;//12:0b1100

各bitの排他的論理和を取ります。

XOR
A B A ^ B
0 0 0
0 1 1
1 0 1
1 1 0

結果はこの表に従います。

論理否定

const uint8_t a = 0b10110;//22
const uint8_t re = ~a;//233:0b11101001

各ビットの論理否定を取ります。1の補数をとる、ともいいます。