こんにちは。
フラグフィルのコードを作ってみたのですが、
start_bit=0で "mask = mask >> (WORD_WIDTH - start_bit);"
が"0"にならずに"0xffffffff"になるのですが、これはどういうことなのでしょうか。算術右シフトをしているのでしょうか?
よろしくお願いします。
#define MASK 0xffffffff
#define WORD_WIDTH 32
int flag_fill (int fill_data, int target_data, int width, int
start_bit)
{
int source_lsb,
source_msb,
filled_data,
out_data;
unsigned int mask;
mask = MASK;
printf("mask = %x", mask);
mask = mask >> (WORD_WIDTH - start_bit);
printf("mask = %x", mask);
source_lsb = target_data & mask;
mask = MASK;
printf("mask = %x", mask);
mask = mask >> (WORD_WIDTH - (width + start_bit));
printf("mask = %x", mask);
source_msb = target_data & ~mask;
filled_data = fill_data;
filled_data = filled_data & mask;
filled_data = filled_data << start_bit;
out_data = source_msb | source_lsb | filled_data;
return out_data;
}
規格上,ビットシフト演算子の左側のオペランドを汎整数拡張したものの幅以上のシフトを使用とした場合は,未定義動作となっています。
次に,VC++はシフト演算をCPUのshlなどのシフト命令に変換することがあります。
# 大抵はそうなるはず。
その場合,32以上のシフトは32で割ったあまりが使われます。
# 80386時代の仕様なので,今は変更があるかもしれませんが。
その結果,32 % 32 = 0なので,ビットシフトは行われません。
早速のレス、ありがとうございます。
32ビット幅(以上)の論理右シフトの場合は
if ((WORD_WIDTH - start_bit) >= 32)
mask = 0;
とすべきということでしょうか?
32なんて即値を使わんようにしましょう。
unsigned int のbit幅を UI_BITS をすれば
if ( start_bit >= UI_BITS ) ...
じゃねぇですか?
> unsigned int のbit幅を UI_BITS をすれば
CHAR_BIT * sizeof(unsigned int)ですかね。
>YuOさん、επιστημηさん、Banさん
レス遅くなり申し訳ありません。
>unsigned int のbit幅を UI_BITS をすれば
というのは
unsigned int のbit幅を UI_BITS とすれば
ということですか?
UI_BITSというマクロ(?)があるのですか?
> UI_BITSというマクロ(?)があるのですか?
UI_BITSの方は、標準にはないですよ。自分で定義してください。
「unsigned int のbit幅を UI_BITS とすれば」ってのは、
数学とかで例えば「(a+b+c)をAとすれば」って言ってるのと日本語的には同じ表現。
意味的には、前述の通り。
> CHAR_BIT * sizeof(unsigned int)ですかね。
で、CHAR_BITの方は、言語標準です。(ヘッダは、Cならlimits.h、C++ならclimits)
ツイート | ![]() |