0

Cに次のコードがval1あり、val2それぞれに格納されている値から特定のビットを抽出し、抽出されたビットに相当する10進数を格納して、後でval1とval2を比較しようval1としています。ここで抽出するビットの範囲を示します。たとえば、2〜2は、3番目のビットを抽出することを意味します。val2nbits

static unsigned int BIT[] = {
0x1,        0x2,        0x4,        0x8,
0x10,       0x20,       0x40,       0x80,
0x100,      0x200,      0x400,      0x800,
0x1000,     0x2000,     0x4000,     0x8000,
0x10000,    0x20000,    0x40000,    0x80000,
0x100000,   0x200000,   0x400000,   0x800000,
0x1000000,  0x2000000,  0x4000000,  0x8000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000
};
int val1, val2;
unsigned long mask_val;
int nbits[2];

nbits[0] = nbits[1] = 2;
val1 = -41;
val2 = -45;

for (i = nbits[0]; i <= nbits[1]; i++)
     mask_val = mask_val|BIT[i];
val1 = (val1 & mask_val) >> nbits[0];
val2 = (val2 & mask_val) >> nbits[0];

上記のこのコードは、32ビットマシンでは希望どおりに機能しますが、特に初期値がに格納されて負の場合、64ビットマシンでは間違った結果にval1なりval2ます。マシンに依存しないようにするには、上記のコードにどのような変更を加える必要がありますか?

4

4 に答える 4

3

1、mask_valを初期化しないと、多くのコンパイラで問題が発生します2、stdint.hを使用すると、valsとmaskのタイプがシステムに依存しなくなります

int8_t
int16_t
int32_t
uint8_t
uint16_t
uint32_t
int64_t
uint64_t

3、テーブルを使用する代わりに、0x1からビットシフトしてみませんか。すなわち

mask_val = mask_val| ( 0x1 << (i - 1) );
于 2012-06-27T18:41:05.427 に答える
1

私があなたのコードのさまざまなバージョンを開発している間、他の人は基本的に私が以下に示すのと同じことを述べました。

あなたのコードが32ビットバージョンで機能した理由はまぐれだったと思います。どうやらそのシステムでは、初期化されていないmask_valがたまたまゼロだったので、「ラッキー」でした。

以下に、独自のコードの3つのバージョンの進行状況を示します。最初に、コードは基本的に変更されていませんが、mask_valを0に初期化し、コードを実行するタイプにtypedefを使用しています。2番目も同じですが、BIT[]テーブルがありません。3番目はループを排除します。

#if 0
#include <stdio.h>

typedef long long valTy;

int main()
{
static unsigned int BIT[] = {
0x1,        0x2,        0x4,        0x8,
0x10,       0x20,       0x40,       0x80,
0x100,      0x200,      0x400,      0x800,
0x1000,     0x2000,     0x4000,     0x8000,
0x10000,    0x20000,    0x40000,    0x80000,
0x100000,   0x200000,   0x400000,   0x800000,
0x1000000,  0x2000000,  0x4000000,  0x8000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000
};
valTy val1, val2;
valTy mask_val;
int i, nbits[2];

printf("\n");

nbits[0] = nbits[1] = 2;
val1 = -41;
val2 = -45;

printf("    val1 = 0x%016llx (%lld)\n", (long long)val1, (long long)val1);
printf("    val2 = 0x%016llx (%lld)\n", (long long)val2, (long long)val2);
printf("\n");

mask_val = 0;
for (i = nbits[0]; i <= nbits[1]; i++)
    mask_val = mask_val|BIT[i];
printf("mask_val = 0x%016llx\n\n", (long long)mask_val);
val1 = (val1 & mask_val) >> nbits[0];
val2 = (val2 & mask_val) >> nbits[0];

printf("    val1 = 0x%016llx (%lld)\n", (long long)val1, (long long)val1);
printf("    val2 = 0x%016llx (%lld)\n", (long long)val2, (long long)val2);
printf("\n");
}

#endif




#if 0
#include <stdio.h>

typedef long long valTy;
#define BIT(bitnum) (1<<bitnum)

int main()
{
valTy val1, val2;
valTy mask_val;
int i, nbits[2];

printf("\n");

nbits[0] = nbits[1] = 2;
val1 = -41;
val2 = -45;

printf("    val1 = 0x%016llx (%lld)\n", (long long)val1, (long long)val1);
printf("    val2 = 0x%016llx (%lld)\n", (long long)val2, (long long)val2);
printf("\n");

mask_val = 0;
for (i = nbits[0]; i <= nbits[1]; i++)
    mask_val = mask_val | BIT(i);
printf("mask_val = 0x%016llx\n\n", (long long)mask_val);
val1 = (val1 & mask_val) >> nbits[0];
val2 = (val2 & mask_val) >> nbits[0];

printf("    val1 = 0x%016llx (%lld)\n", (long long)val1, (long long)val1);
printf("    val2 = 0x%016llx (%lld)\n", (long long)val2, (long long)val2);
printf("\n");
}

#endif

#include <stdio.h>

typedef long long valTy;
#define BIT(bitnum) (1<<bitnum)

int main()
{
valTy val1, val2;
valTy mask_val;
int i, nbits[2];

printf("\n");

nbits[0] = nbits[1] = 2;
val1 = -41;
val2 = -45;

printf("    val1 = 0x%016llx (%lld)\n", (long long)val1, (long long)val1);
printf("    val2 = 0x%016llx (%lld)\n", (long long)val2, (long long)val2);
printf("\n");

mask_val = 0;
{
    valTy maskTop = ((BIT(nbits[0])-1)<<1)|1;
    valTy maskBottom = BIT(nbits[1])-1;
    mask_val = maskTop & ~maskBottom;
}
printf("mask_val = 0x%016llx\n\n", (long long)mask_val);
val1 = (val1 & mask_val) >> nbits[0];
val2 = (val2 & mask_val) >> nbits[0];

printf("    val1 = 0x%016llx (%lld)\n", (long long)val1, (long long)val1);
printf("    val2 = 0x%016llx (%lld)\n", (long long)val2, (long long)val2);
printf("\n");
}
于 2012-06-27T18:50:19.857 に答える
0

コードはまだ記述どおりに機能していますが、符号ビットが32ビットマークよりも高いと思われます。この投稿を参照して、役立つかどうか教えてください: 64ビットWindowsでのlongのビットサイズはどれくらいですか?

于 2012-06-27T18:25:30.280 に答える
0

あなたの問題はmask_val初期化されていないという事実から来ていると思います。ループが開始する前にビットが設定されないようにするには、0で初期化する必要があります。

于 2012-06-27T18:28:11.733 に答える