エンジニアは豆電球の夢を見るか

日々の学びを書き綴る。忘れてしまうから。

ビット演算の基礎とビット抽出

ビット演算子

  • 左辺と右辺の同じ位置にあるビットを比較する
演算子 記述例 意味 概要
& a = b & 0x01 ビットAND 両方のビットが「どちらも」1の場合だけ「1」を出力する
| a = b | 0x01 ビットOR 両方のビットの「どちらかが」1の場合だけ「1」を出力する
^ a = b ^ 0x01 ビットXOR 両方のビットの「どちらかが」異なる場合だけ「1」を出力する

ビット反転

演算子 記述例 意味 概要
~ a = ~a ビットNOT 右辺の値の各ビットに対して「1は0」に「0は1」にする

ビットシフト

演算子 記述例 意味 概要
<<= a = a << 2 左シフト
>>= a = a >> 2 右シフト
  1. ビット演算
  2. ビットフラグ
  3. ビットマスク

ビットフラグの作り方

16進数で2進数の1桁ずつの立っているビットフラグを作成、 2進数で1桁ずつ立てればいいので、2の倍数で数値を作っていく

int BIT_FLAG1   = 0x0001;  //  2進数 : (0000 0000 0000 0001)
int BIT_FLAG2   = 0x0002;  //  2進数 : (0000 0000 0000 0010)
int BIT_FLAG4   = 0x0004;  //  2進数 : (0000 0000 0000 0100)
int BIT_FLAG8   = 0x0008;  //  2進数 : (0000 0000 0000 1000)
int BIT_FLAG16  = 0x0010;  //  2進数 : (0000 0000 0001 0000)
int BIT_FLAG32  = 0x0020;  //  2進数 : (0000 0000 0010 0000)
int BIT_FLAG64  = 0x0040;  //  2進数 : (0000 0000 0100 0000)
int BIT_FLAG128 = 0x0080;  //  2進数 : (0000 0000 1000 0000)

変数にフラグを立てる

int flag = BIT_FLAG1 | BIT_FRAG4;   //  1つ目と3つ目にフラグを立てる
  • 2進数で表すと
(0000 0001) OR (0000 0100) = (0000 0101)

ビット演算のサンプル

//  2進数表示のためのメソッド
void printb(unsigned int v) {
  unsigned int mask = (int)1 << (sizeof(v) * CHAR_BIT - 1);
  do putchar(mask & v ? '1' : '0');
  while (mask >>= 1);
}

int main(int argc, const char * argv[]) {
    
    int BIT_FLAG1   = 0x0001;
    int BIT_FLAG2   = 0x0002;
    int BIT_FLAG4   = 0x0004;
    int BIT_FLAG8   = 0x0008;
    int BIT_FLAG16  = 0x0010;
    int BIT_FLAG32  = 0x0020;
    int BIT_FLAG64  = 0x0040;
    int BIT_FLAG128 = 0x0080;
    
    printf("=== OR演算 ===\n");
    int flag = BIT_FLAG1 | BIT_FLAG2;
    printb(BIT_FLAG1);
    printf("\n");
    printb(BIT_FLAG2);
    printf("\n");
    printb(flag);
    printf("\n");
  
    // === OR演算 ===
    // 00000000000000000000000000000001
    // 00000000000000000000000000000010
    // 00000000000000000000000000000011
  
    printf("=== AND演算 ===\n");
    int flag1 = BIT_FLAG1 & BIT_FLAG2;
    printb(BIT_FLAG1);
    printf("\n");
    printb(BIT_FLAG2);
    printf("\n");
    printb(flag1);
    printf("\n");
  
   // === AND演算 ===
   //  00000000000000000000000000000001
   //  00000000000000000000000000000010
   //  00000000000000000000000000000000
    
    printf("=== XOR演算 ===\n");
    int flag3 = BIT_FLAG1 & BIT_FLAG2;
    printb(BIT_FLAG1);
    printf("\n");
    printb(BIT_FLAG2);
    printf("\n");
    printb(flag3);
    printf("\n");
    
    // === XOR演算 ===
    // 00000000000000000000000000000001
    // 00000000000000000000000000000010
    // 00000000000000000000000000000011
  
    printf("=== NOT演算 ===\n");
    printb(BIT_FLAG1);
    printf("\n");
    BIT_FLAG1 = ~BIT_FLAG1;
    printb(BIT_FLAG1);
    printf("\n");
    
    // === NOT演算 ===
    // 00000000000000000000000000000001
    // 11111111111111111111111111111110
  
    return 0;
}

フラグの抽出

void main()
{
    int flag = ( BIT_FLAG_1 | BIT_FLAG_4 );

    bit_extractor(flag);
}

void bit_extractor( int flag )
{
    //  flag = 0000 0000 0000 0101

    if( ( flag & BIT_FLAG_1 ) == 1 )  // true
    { 
        funcA(); 
    }
    if( ( flag & BIT_FLAG_2 ) == 1 )  // false
    { 
        funcB();
    }
    if( ( flag & BIT_FLAG_4 ) == 1 )   // true
    {
        funcC();
    }
    if( ( flag & BIT_FLAG_8 ) == 1 )   // false
    {
        funcD();
    }
}

Rasberry Pi 3以降にCentOSを入れる

CentOSダウンロード

Rasberry Pi3の場合

http://buildlogs.centos.org/centos/7/isos/armhfp/

今回はラズパイに入れるので赤い部分のファイルをダウンロード

f:id:D4iki:20191214084004p:plain

Rasberry Pi3+以降の場合

http://isoredirect.centos.org/altarch/7/isos/armhfp/CentOS-Userland-7-armv7hl-RaspberryPI-Minimal-1908-sda.raw.xz

最新のバージョンをダウンロード(このバージョン違いでOSが起動しなくて3時間が溶けた) f:id:D4iki:20191214083936p:plain

microSDに焼く

「DD for Windows」で焼く

調べた限り、よくこのソフトが使われているが、Windows10の場合、互換モードで起動が必要らしい - https://www.si-linux.co.jp/techinfo/index.php?DD%20for%20Windows#s74c46f6

「balena Etcher」で焼く

こっちは公式がおすすめしているらしい、すごい簡単 - https://www.balena.io/etcher/

起動

CPUはなぜ「8ビット」「32ビット」「64ビット」なのか

疑問

  • 私の知っている限りCPUのビット数はすごい規則性のありそうな数字で性能が上がっている印象があったが、なぜその数字なのか
  • 一見した感じ8の倍数な気がするが、それなら24ビットCPUはなぜ無いのか

調査結果

8ビットの倍数である意味

標準的な文字コードとして、ASCII(7ビット)が普及し、その後も8ビットが基本の文字コードが生まれ続けているため、人間が理解できる文字を効率よく処理するために8の倍数になった

2ビットの冪乗である意味

メモリを確保するためにどれだけのサイズが必要かを計算するときに、ビットシフトをすることで効率よく計算ができるため

人間を例にすると

759個のリンゴを1箱[12]個入る箱に入れる場合、全部を箱に入れるのに何箱必要か

759 / 12 

を計算する必要があるが、計算するのが面倒くさい。 箱の容量が[10]個だったらどうだろうか

759 / 10

全てのリンゴを箱に入れるには[76個]の箱が必要だとすぐに計算できる

これは私たちが日頃、10で桁を上げているからで、コンピューターからすれば使いなれている、2で桁を上げる2進法が一番早く計算できる。

まとめ

現在のCPUは、効率よく文字を表現するために8ビットの倍数、早く計算するために2ビットの冪乗の両方に当てはまる「8ビット」「32ビット」「64ビット」のCPUになっている

「2進数」「10進数」「16進数」の基礎

各進数の特徴

「2、10、16」は「進数」つまり、桁が上がるまでに使う数字(文字)の数を表している

2進数

使う数字は「0、1」

0,1,10,1111,0000,001010,

桁上がり

0,1,10,11,100,101,110,

10進数

使う数字は「0、1、2、3、4、5、6、7、8、9」

 0,11,42,56,424,1000

桁上がり

...8,9,10,11,12,13

16進数

使う数字は「0、1、2、3、4、5、6、7、8、9、a、b、c、d、e、f」

0,11,1a2,5e,fc,a1,aef,ff15,

桁上がり

0,1,2...f,10,11...1f,20,21,22

「2、10、16」進数は互いに変換できる

2進数 => 10進数

  1. 2進数「0101」
  2. 2進数を10進数に変換する場合の10進数の基準値
  3. 2進数で1となっている桁に該当する基準値を足す
  4. 足した値が2進数を10進数に変換した値「5」

f:id:D4iki:20191209022723p:plain

10進数 => 16進数

  1. 10進数「58910」
  2. 割り切れなくなるまで商を16で割り続け、余りと割り切れなくなった商を矢印の方向(計算と逆順)につなぎ合わせる
  3. 「15,10,1,14」の中で2桁ある数字を16進数の対応する文字に置き換える「fa1e」

f:id:D4iki:20191209022746p:plain

16進数 => 10進数

  1. 16進数「1ef3」
  2. 16進数から10進数へ変換する為に10進数の基準値をかける
  3. 計算で出た値を全て足す

f:id:D4iki:20191209022751p:plain

10進数 => 2進数

  1. 10進数「25」
  2. 割り切れなくなるまで、商を2で割り続け、余りと割り切れなくなった商(0か1)を矢印の方向(計算と逆順)につなぎ合わせる
  3. つなぎ合わせた値が10進数を2進数に変換した値「11001」

f:id:D4iki:20191209022740p:plain

UnityEditorのグリッドの表示がおかしくなっ時にチェックしたい項目

私が遭遇した現象

2D

なんかすごいグリッドラインが太くなっていた f:id:D4iki:20191120005639p:plain

3D

もうよくわからないぐらいおかしい f:id:D4iki:20191120005647p:plain

解決方法

エディタの画面ヘッダー部分の太陽マークをOnにしたら直った

  • 太陽マークをマウスオーバーした時の文章(素人翻訳)

    オンに切り替えると、シーンの照明が使用されます。 オフに切り替えると、シーンビューカメラに接続されたライトが使用されます。 f:id:D4iki:20191120010957p:plain

調べても同じ現象の記事が出てこなくてちょっと焦ったので、メモとして書き残す

Gitとは?

Gitとは?

  • 分散型のバージョン管理システム
  • ローカル環境でコードの変更履歴を保存(コミット)することができる。
    • サーバーにコミット情報を保存することもできる(プッシュ)
    • サーバーにコミット情報を保存できるサービスで有名なのがGitHub
  • ファイルの状態を過去に戻したりできる