WGC1 第3章2進数の算術演算子とビット演算 3.6 ビットフィールドとデータのパック その2
2桁のみの日付形式というのは、2000年問題など、配慮に欠けているデータ形式。
そのため、年を0〜65535とし、32bitのデータ形式を使用する。
x86のunsigned intのイメージ
31 | 16 | 15 | 8 | 7 | 0 | |||||||||||||||||||||||||
> | > | > | > | > | > | > | > | > | > | > | > | > | > | > | 年(0〜65535) | > | > | > | > | > | > | > | 月(1〜12) | > | > | > | > | > | > | 日(1〜31) |
この日付方式では、年の範囲を除いた2バイト分に月と日の各フィールドにそれぞれ1バイトを割り当てている。
余分な領域はあるが、1バイトのフィールドなら、アプリケーションでは、バイトオブジェクトとして簡便に操作できるので
バイトアクセスをサポートするプロセッサにおいては、フィールドのパック、アンパックに要するオーバーヘッドを軽減できる。
32bit=4バイト使用するのなら、short,char,charでもサイズは変わらない。
この形式の目的は、サイズの削減ではなく、パックすることで、パッケージ化されている、カプセル化されているということ。
データをダブルワード変数(unsigned intのイメージ)にパックすることにより、3つの別変数ではなく、単一のデータ値として扱える。
その場合、このデータに対する操作は3つの個別の命令ではなく、単一の命令で済む。
また、この形式では、符号なし整数の比較により、日付を簡単に比較できる。~
高水準言語の中には、パックされたデータのサポートが標準で組み込まれているものがある。
C言語では、次のような構造体を定義できる。
struct { unsigned bits0_3 :4; unsigned bits4_11 :8; unsigned bits12_15 :4; unsigned bits16_23 :8; unsigned bits24_31 :8; }packed_data;
C/C++コンパイラが32bitのダブルワードの値をこれらの各フィールドを
どのように割り当ててるかは、コンパイラ依存。ビット列の中のビットの
配置もコンパイラ依存。
ビットフィールド宣言を使用する場合は、移植性はないと考えてまず間違いない
実験コード
#include #include struct { unsigned bits0_3 :4; unsigned bits4_11 :8; unsigned bits12_15 :4; unsigned bits16_23 :8; unsigned bits24_31 :8; }packed_data; struct { unsigned year :7; unsigned month :4; unsigned day :5; } short_date; int main(int argc, char* argv[]){ packed_data.bits0_3 = 0xF; packed_data.bits4_11 = 0xFF; packed_data.bits12_15 = 0x0; packed_data.bits16_23 = 0xAA; packed_data.bits24_31 = 0x55; printf("each filed = %#x, %#x, %#x, %#x, %#x\n", packed_data.bits0_3, packed_data.bits4_11, packed_data.bits12_15, packed_data.bits16_23, packed_data.bits24_31 ); printf("data filed = %#x\n", packed_data); short_date.year = 9; /* 2009 */ short_date.month = 1; short_date.day = 31; printf("The short date is %02d/%02d/%02d (year/month/day), size is %d\n", short_date.year, short_date.month, short_date.day, sizeof(short_date)); return 1; }
コンパイル
[oc@centos5 3.6bitfield_and_datapack]$ gcc packeddata.c -o packeddata
結果
[oc@centos5 3.6bitfield_and_datapack]$ ./packeddata each filed = 0xf, 0xff, 0, 0xaa, 0x55 data filed = 0x55aa0fff The short date is 09/01/31 (year/month/day), size is 4
コンパイル
D:\workspace\C_SandBox\10BOOKs\WGC1\3.6bitfield_and_datapack>cl packeddata.c Microsoft(R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. packeddata.c Microsoft (R) Incremental Linker Version 9.00.21022.08 Copyright (C) Microsoft Corporation. All rights reserved. /out:packeddata.exe packeddata.obj