我有兴趣获得欧几里得除法的余数,即对于一对整数 (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 欧几里得除法。如果我需要在一个 ^d 数组与 am^d 内核之间进行关联,我需要 n^d * m^d * d 欧几里得除法。对于 100x100x100 点的 3d 图像和 5*5*5 点的内核,这已经是约 4 亿欧几里得分割。