0

奇妙な問題が発生しています。動的に作成された2D配列Contentがあり、高さは_h、幅は_wです(私の実装では、行が最初のパラメーターで、列が2番目であり、コンテキストで意味があります)。2つのインデックスが範囲外になる可能性があります。これは仕様によるものであり、範囲外の場合、インデックスは配列に「ラップアラウンド」されます。

Content[v.iget()%_h][u.iget()%_w];

vとuは私自身のクラスのオブジェクトです。内部には__int64値があり、iget()は次のようになります。

return value>>precision;

通常の32ビット整数を返します。このint値を高さまたは幅で%で「ラップ」します。明らかに、余りは常に0 <=r<maxです。したがって、この%操作は、起こりうる範囲外の状況に対する保護も提供しますが、この行で正確にアクセス違反が発生することがあります。vとuの値を見ると、-7753978124のようなものです。実際、私のコンテキストで負の数が発生することは想定されていません(したがって、原因をまだ探していません)が、とにかく、。 iget()はそれを通常の整数に変換し、%_ hまたは%_wはそれを境界に入れる必要がありますが、代わりにアクセス違反が発生します。どうすればこれが可能ですか?

4

2 に答える 2

2

通常の整数に変換する必要があります

いいえ。 (-1 % 2) == -1

そのため、式x % maxは (-max..max) の範囲の値を返します。

それが最初の問題です。

2番目の問題はこれです:

__int64 a = 0xffffffff00000000;
int b = a >> 32;
printf("%d\n", b);

0xffffffff00000000 >> 32これは0xffffffff負の数-1です (signed 32bit int の場合)。

次のような式を使用して問題を解決できます。

((x % width) + width)%width

または、if/else でインデックスを修正できます。

x %= width;
if (x < 0)
    x += width;

unsigned int別の方法として、iget() を returnにすることもできますが 2 の累乗ではないすべての幅と高さについて、負のインデックスを適切にラップすることはできません。

于 2012-06-01T02:38:25.820 に答える
1

負の値に達していないことを確実にするために、次のようにインデックスを実装できます。また、モジュロを計算するよりも高速である必要があります。これは、ステートメントがタイトなループ内で発生する場合に重要な考慮事項になります。

__int64 v = v.iget();
__int64 u = u.iget();
Content[v < 0 ? 0 : v > _h ? _h : v][u < 0 ? 0 : u > _w ? _w : u];
于 2012-06-01T04:04:14.723 に答える