[C言語] Cパズルブック 1.5.3 関係演算子と条件演算子 加算代入演算子 +=

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

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

パズルなので楽しめていますが、実務でそのまま使うのは顰蹙ものでしょうか。せめて括弧で補足したいところです。

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

int main() {
    int x , y, z;

    x = 3; y = 3; z = 1;
    
    PRINT(z += x < y ? x++ : y++);
    PRINT(y); PRINT(z);

    // PRINT(z += (x < y ? x++ : y++));

    // 計算1: x < y
    //       3 < 3 は FALSE
    // 計算2: x < y ? x++ : y++
    //       FALSEはy++
    //       y++は評価時はまだ加算しないため3のまま
    // 計算3: z += Rt
    //       z = z + Rt = 1 + 3 = 4

    // 計算4: y
    //       y++評価後は1増えるので4になる
    // 計算5: z = 4
    
    // よって出力は4, 4, 4となる

    return 0;
}
4
4
4

[C言語] Cパズルブック 1.5.2 関係演算子と条件演算子 後置インクリメント x++

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

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

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

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

    x += y += z;

    PRINT(x < y ? x++ : y++);
    PRINT(x); PRINT(y);

    // x = 3; y = 2; z = 1;
    // 計算1: x < y
    //       3 < 2 は FALSE
    // 計算2: x < y ? x++ : y++
    //       FALSEはy++
    //       y++は評価時はまだ加算しないため2のまま

    // 計算3: x
    //       x++は評価されなかったので3のまま
    // 計算4: y
    //       y++評価後は1増えるので3になる
    
    // よって出力は2, 3, 3となる

    return 0;
}
2
3
3

[C言語] Cパズルブック 1.5.1 関係演算子と条件演算子 三項演算子 x ? y : z

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

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

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

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

    x += y += z;
    PRINT(x < y ? y : x);

    PRINT((x < y) ? y : x);

    // x += (y += z)
    // 計算1: y += z
    //       y = y + z = 2
    // 計算2: x += (y += z)
    //       x = x + Rt = 1 + 2 = 3      

    // (x < y) ? y : x
    // 計算3: x < y
    //       3 < 2 は FALSE
    // 計算4: (x < y) ? y : x
    //       FALSEはx
    
    // よって出力は3となる

    return 0;
}
3
3

[C言語] Cパズルブック 1.5 関係演算子と条件演算子

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

Cパズルブック 1.5のコードおよび出力は以下の通りです。

次回以降で各問解答について詳説します。

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

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

    x += y += z;
    PRINT(x < y ? y : x);

    PRINT(x < y ? x++ : y++);
    PRINT(x); PRINT(y);

    PRINT(z += x< y ? x++ : y++);
    PRINT(y); PRINT(z);

    x = 3; y = z = 4;
    PRINT((z >= y >= x) ? 1 : 0);
    PRINT( z >= y && y >= x);

    return 0;
}
3
2
3
3
4
4
4
0
1

[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