WGC1 第3章2進数の算術演算子とビット演算 3.7データのバックとアンパック
最上位ビットを空ける
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