問題
下記は、論理積を用いて整数型が偶数か奇数かを判断し、偶数なら0,奇数なら1を表示するプログラムである。完成させよ。
#include <stdio.h> int main() { const unsigned int target = 11235; const unsigned int isOdd = ; printf("%d\n", isOdd); return 0; }
ビッド演算とは、各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
各ビットの論理積を取ります。
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
各ビットの論理和を取ります。
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の排他的論理和を取ります。
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の補数をとる、ともいいます。