[C言語] Cパズルブック 1.4.8-10 ビット演算子 シフト演算子 <<, >>

『Cパズルブック』(Alan R.Feuer, 1985)
[Mac M2 Pro 12CPU, MacOS Ventura 13.3.1, clang 14.0.3]

問1.4.8から1.4.10の解法は以下の通りです。

#include <stdio.h>
#define PRINT(int) printf("%d\n",int)

int main() {
    int x , y;
    
    x = 1; y = -1;

    // 問1.4.8
    x <<= 3;
    PRINT(x);   // 8

    // 計算1: x <<= 3
    // x = 0b00000001
    // <<3 
    // --------------
    //     0b00001000 

    // よって10進数8となる

    // 問1.4.9
    y <<= 3;
    PRINT(y);   // -8

    // 計算1: y <<= 3
    // y = 0b11111111
    // <<3 
    // --------------
    //     0b11111000(負数)
    // 反転 0b00000111 + 1 = 0b00001000 = 10進数8
    // マイナスを付けて-8

    // 問1.4.10
    // y = -8 // 問1.4.9の続き
    y >>= 3;
    PRINT(y);   // -1

    // 計算1: y >>= 3
    // y = 0b11111000
    // >>3 : 2^3 = 8で割るため-1になる
    // 古い計算機では符号を保存しないこともあり、8割る8で1になる場合がある

    // 別解
    // 計算1: y >>= 3
    // y = 0b11111000
    // >>3
    // ---------------
    // y = 0b11111111 3桁右シフトして左桁は1を追加
    // 反転 0b00000000 +1 = 0b00000001 = 10進数1
    // マイナスを付けて10進数-1

    return 0;
}
8
-8
-1

[C言語] Cパズルブック 1.4.7 ビット演算子 ビットXOR ^

『Cパズルブック』(Alan R.Feuer, 1985)
[Mac M2 Pro 12CPU, MacOS Ventura 13.3.1, clang 14.0.3]

問1.4.7の解法は以下の通りです。

#include <stdio.h>
#define PRINT(int) printf("%d\n",int)

int main() {
    int x , y;
    
    x = 1; y = -1;

    // 問1.4.7
    PRINT( x ^ x);   // 0

    // 計算1: x ^ x
    // x = 0b00000001
    // x = 0b00000001
    // ^ --------------
    //     0b00000000  

    // よって10進数0となる

    return 0;
}
0

[C言語] Cパズルブック 1.4.6 ビット演算子 ビット反転演算子~

『Cパズルブック』(Alan R.Feuer, 1985)
[Mac M2 Pro 12CPU, MacOS Ventura 13.3.1, clang 14.0.3]

問1.4.6の解法は以下の通りです。符号付き整数型ですからビット番号7(右から8番目)は符号を表します。

計算3で少し手間取りました。

#include <stdio.h>
#define PRINT(int) printf("%d\n",int)

int main() {
    int x , y;
    
    x = 1; y = -1;

    // 問1.4.6
    PRINT( ~x | x);   // -1

    // ビット反転演算子~を優先
    PRINT(~x);        // -2
    PRINT( (~x) | x); // -1

    // 計算1: ~x
    // x = 0b00000001
    // ~ --------------
    //     0b11111110     

    // 計算2: (~x) | x
    // Lt = 0b11111110
    // x  = 0b00000001
    // | -------------
    //      0b11111111(符号付き -128から127まで)

    // 計算3:10進数へ変換
    // 0b11111111の最上位ビット(右から8番目)は1なので負数
    // 反転したビットに1を加える
    // 0b00000000 + 1 = 0b00000001 = 10進数1
    // 負数なのでマイナスを付けて10進数-1になる

    return 0;
}
-1
-2
-1

[C言語] Cパズルブック 1.4.5 ビット演算子 論理否定演算子 !

『Cパズルブック』(Alan R.Feuer, 1985)
[Mac M2 Pro 12CPU, MacOS Ventura 13.3.1, clang 14.0.3]

問1.4.5の解法は以下の通りです。

#include <stdio.h>
#define PRINT(int) printf("%d\n",int)

int main() {
    int x , y;
    
    x = 1; y = -1;

    // 問1.4.5
    PRINT( !x | x);   // 1

    // 論理否定演算子 !を優先
    PRINT( (!x) | x); // 1

    // 計算1: !x
    // x = 0b00000001 = TRUE
    // ! --------------
    //     FALSE or 0

    // 計算2: (!x) | x
    // Lt = 0b00000000 = FALSE
    // x  = 0b00000001 = TRUE
    // | -------------
    //      TRUE or 1

    // よってTRUE(10進数1)になる

    return 0;
}
1
1

[C言語] Cパズルブック 1.4.4 ビット演算子 論理AND

『Cパズルブック』(Alan R.Feuer, 1985)
[Mac M2 Pro 12CPU, MacOS Ventura 13.3.1, clang 14.0.3]

問1.4.4の解法は以下の通りです。

#include <stdio.h>
#define PRINT(int) printf("%d\n",int)

int main() {
    int x , y, z;
    
    // 先頭に0を付けると8進数になる
    x = 03; y = 02; z = 01;

    // 問1.4.4
    PRINT( x & y && z);   // 1

    // ビットAND &を優先
    PRINT( (x & y) && z); // 1

    // 計算1: x & y
    // x = 0b00000011
    // y = 0b00000010
    // & --------------
    //     0b00000010

    // 計算2: (x & y) && z
    // Lt = 0b00000010 != 0 = TRUE
    // z  = 0b00000001 != 0 = TRUE
    // && -------------
    //      TRUE or 1

    // よってTRUE(10進数1)になる

    return 0;
}
1
1

[C言語] Cパズルブック 1.4.3 ビット演算子 ビットXOR

『Cパズルブック』(Alan R.Feuer, 1985)
[Mac M2 Pro 12CPU, MacOS Ventura 13.3.1, clang 14.0.3]

問1.4.3の解法は以下の通りです。

#include <stdio.h>
#define PRINT(int) printf("%d\n",int)

int main() {
    int x , y, z;
    
    // 先頭に0を付けると8進数になる
    x = 03; y = 02; z = 01;

    // 問1.4.3
    PRINT( x ^ y & ~z);   // 1

    // 補数~,ビット積&を優先
    PRINT( x ^ (y & (~z))); // 1

    // 計算1: ~z(zの補数)
    // z = 0b00000001
    // ~ --------------
    //     0b11111110

    // 計算2: y & ~z
    // y  = 0b00000010
    // ~z = 0b11111110
    // & --------------
    //      0b00000010

    // 計算3: x ^ (y & ~z)
    // x  = 0b00000011
    // Rt = 0b00000010
    // ^ --------------
    //      0b00000001
    // ビットXOR:同じ0,違う1
    // よって10進数1になる

    return 0;
}
1
1

[C言語] Cパズルブック 1.4.2 ビット演算子 ビット補数

『Cパズルブック』(Alan R.Feuer, 1985)
[Mac M2 Pro 12CPU, MacOS Ventura 13.3.1, clang 14.0.3]

問1.4.2の解法は以下の通りです。

#include <stdio.h>
#define PRINT(int) printf("%d\n",int)

int main() {
    int x , y, z;
    
    // 先頭に0を付けると8進数になる
    x = 03; y = 02; z = 01;

    // 問1.4.2
    PRINT( x | y & ~z);   // 3

    // 補数~,ビット積&を優先
    PRINT( x | (y & (~z))); // 3

    // 計算1: ~z(zの補数)
    // z = 0b00000001
    // ~ --------------
    //     0b11111110

    // 計算2: y & ~z
    // y  = 0b00000010
    // ~z = 0b11111110
    // & --------------
    //      0b00000010

    // 計算3: x | (y & ~z)
    // x  = 0b00000011
    // Rt = 0b00000010
    // | --------------
    //      0b00000011
    // よって10進数3になる

    return 0;
}
3
3

[C言語] Cパズルブック 1.4.1 ビット演算子 ビットAND

『Cパズルブック』(Alan R.Feuer, 1985)
[Mac M2 Pro 12CPU, MacOS Ventura 13.3.1, clang 14.0.3]

問1.4.1の解法は以下の通りです。

#include <stdio.h>
#define PRINT(int) printf("%d\n",int)

int main() {
    int x , y, z;
    
    // 先頭に0を付けると8進数になる
    x = 03; y = 02; z = 01;

    // 問1.4.1
    PRINT( x | y & z);   // 3

    // ビットAND &を優先
    PRINT( x | (y & z)); // 3

    // 計算1: y & z
    // y = 0b00000010
    // z = 0b00000001
    // & --------------
    //     0b00000000

    // 計算2: x | 00
    // x  = 0b00000011
    // 00 = 0b00000000
    // | --------------
    //      0b00000011
    // よって10進数3になる

    return 0;
}
3
3

[C言語] Cパズルブック 1.4 ビット演算子 

『Cパズルブック』(Alan R.Feuer, 1985)
[Mac M2 Pro 12CPU, MacOS Ventura 13.3.1, clang 14.0.3]

昨年2022年12月以来のCパズルブックです。

コードと出力は以下の通りです。

次回以降、各行について詳説します。

#include <stdio.h>
#define PRINT(int) printf("%d\n",int)

int main() {
    int x , y, z, a;
    
    // 先頭に0を付けると8進数になる
    x = 03; y = 02; z = 01; a = 010;

    printf("前半\n");

    PRINT( x | y & z);   // 3
    PRINT( x | y & ~ z); // 3
    PRINT( x ^ y & ~ z); // 1
    PRINT( x & y && z);  // 1

    // 追加
    PRINT( ~ z);         //-2
    PRINT(a);            // 8 8進数になっているか確認

    printf("後半\n");

    x = 1; y = -1;
    PRINT( ! x | x);     // 1
    PRINT( ~ x | x);     //-1
    PRINT( x ^ x);       // 0
    x <<= 3; PRINT(x);   // 8
    y <<= 3; PRINT(y);   //-8
    y >>= 3; PRINT(y);   //-1

    return 0;
}
前半
3
3
1
1
-2
8
後半
1
-1
0
8
-8
-1