ユークリッド除算の剰余を取得することに興味があります。つまり、整数のペア (i、n) について、次のような r を見つけます。
i = k * n + r, 0 <= r < |k|
簡単な解決策は次のとおりです。
int euc(int i, int n)
{
int r;
r = i % n;
if ( r < 0) {
r += n;
}
return r;
}
しかし、これを何千万回も実行する必要があるので(多次元配列のイテレータ内で使用されます)、できれば分岐は避けたいです。要件:
- 分岐するが高速であることも望ましい。
- 正の n に対してのみ機能するソリューションは許容されます (ただし、負の i に対して機能する必要があります)。
- n は前もってわからず、> 0 かつ < MAX_INT の任意の値にすることができます
編集
実際には間違った結果を得るのは非常に簡単なので、期待される結果の例を次に示します。
- euc(0, 3) = 0
- euc(1, 3) = 1
- euc(2, 3) = 2
- euc(3, 3) = 0
- euc(-1, 3) = 2
- euc(-2, 3) = 1
- euc(-3, 3) = 0
これを最適化しても意味がないのではないかと心配する人もいます。境界外のアイテムが元の配列を繰り返す「仮想配列」内のアイテムに置き換えられる多次元イテレータにこれが必要です。したがって、配列 x が [1, 2, 3, 4] の場合、仮想配列は [...., 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]、たとえば x[-2] は x 1など...
次元 d の nd 配列の場合、すべての点について d ユークリッド除算が必要です。am^d カーネルを使用して an^d 配列を相関させる必要がある場合は、n^d * m^d * d ユークリッド除算が必要です。100x100x100 ポイントの 3D 画像と 5*5*5 ポイントのカーネルの場合、それはすでに ~ 4 億のユークリッド分割です。