読者です 読者をやめる 読者になる 読者になる

WGC1 第3章2進数の算術演算子とビット演算 3.7データのバックとアンパック

C

最上位ビットを空ける

31 21 20 14 13 0
> > > > > > > > > > 第1フィールド000-999 > > > > > > 第2フィールド00-99 > > > > > > > > > > > > 第3フィールド 0000-9999

ソース上のssn2
32bit符号なし整数で単純に比較することができる。

バイト境界に合わせる

31 22 21 8 7 0
> > > > > > > > > 第1フィールド000-999 > > > > > > > > > > > > > 第3フィールド 0000-9999 > > > > > > > 第2フィールド00-99

ソース上のssn3
第3フィールドがバイト境界から始まっている。
アセンブラでのアクセスは、バイト境界のデータに簡単にアクセスできる。

#include <stdlib.h>
#include <stdio.h>

/* Soucail Security Number */

#define SSN2_FIST_FIELD_SIZE_        (10)
#define SSN2_SECOND_FIELD_SIZE        (7)
#define SSN2_THIRD_FIELD_SIZE       (14)

#define SSN3_FIST_FIELD_SIZE_        (10)
#define SSN3_SECOND_FIELD_SIZE        (8)
#define SSN3_THIRD_FIELD_SIZE        (14)


struct {
    unsigned first_filed_id      :16;
    unsigned second_filed_id     :8;
    unsigned third_filed_id      :16;
}ssn1;


int main(int argc, char* argv[]){
    
    unsigned int ssn2 = 0;  /* 1st 2nd 3rd */
    unsigned int ssn3 = 0;  /* 1st 3rd 2nd */
    
    /* 123-45-6789 */
    ssn1.first_filed_id  = 123;
    ssn1.second_filed_id = 45;
    ssn1.third_filed_id = 6789;
    printf("ssn1 = %#x\n", ssn1);
    printf("ssn1 1st= %d, 2nd = %d, 3rd = %d, size = %d\n", 
            ssn1.first_filed_id,
            ssn1.second_filed_id,
            ssn1.third_filed_id,
            sizeof(ssn1)
          );
    /* 123  45 6789 */
    
    ssn2 = 123 << SSN2_SECOND_FIELD_SIZE;
    ssn2 = ( ssn2 | 45 ) << SSN2_THIRD_FIELD_SIZE;
    ssn2 = ssn2 | 6789 ;
    printf("ssn2 = %#x\n", ssn2);
    printf("ssn2 1st= %d, 2nd = %d, 3rd = %d, size = %d\n",
            ssn2 >>(SSN2_THIRD_FIELD_SIZE + SSN2_SECOND_FIELD_SIZE),
            (ssn2 >> SSN2_THIRD_FIELD_SIZE) & 0x7F, 
            ssn2 & 0x3FFF,
            sizeof(ssn2)
          );
    
    /* 123  6789  45 */
    ssn3 = 123 << SSN3_THIRD_FIELD_SIZE;
    ssn3 = ( ssn3 | 6789 ) << SSN3_SECOND_FIELD_SIZE;
    ssn3 = ssn3 | 45;
    printf("ssn3 = %#x\n", ssn3);
    printf("ssn3 1st= %d, 2nd = %d, 3rd = %d, size = %d\n",
            ssn3 >> (SSN3_THIRD_FIELD_SIZE + SSN3_SECOND_FIELD_SIZE),
            ssn3 & 0x7F, 
            (ssn3 >>SSN3_SECOND_FIELD_SIZE) & 0x3FFF,
            sizeof(ssn2)
          );
          
   return 0;
}

環境

コンパイル

[oc@centos5 3.7_Packing_adn_Unpacking_Data]$ gcc -o packing_and_unpacking packing_and_unpacking.c

結果

[oc@centos5 3.7_Packing_adn_Unpacking_Data]$ ./packing_and_unpacking
ssn1 = 0x2d007b
ssn1 1st= 123, 2nd = 45, 3rd = 6789, size = 8
ssn2 = 0xf6b5a85
ssn2 1st= 123, 2nd = 45, 3rd = 6789, size = 4
ssn3 = 0x1eda852d
ssn3 1st= 123, 2nd = 45, 3rd = 6789, size = 4







Randall Hyde、鵜飼 文敏、まつもと ゆきひろ、後藤 正徳、トップスタジオ