负数的模数

fre*_*oma 18 algorithm math modulo

可能重复:
负数的Mod正在融化我的大脑!

我想知道是否有一个更好的算法,我正在尝试做什么:

wrapIndex(-6, 3) = 0
wrapIndex(-5, 3) = 1
wrapIndex(-4, 3) = 2
wrapIndex(-3, 3) = 0
wrapIndex(-2, 3) = 1
wrapIndex(-1, 3) = 2
wrapIndex(0, 3) = 0
wrapIndex(1, 3) = 1
wrapIndex(2, 3) = 2
wrapIndex(3, 3) = 0
wrapIndex(4, 3) = 1
wrapIndex(5, 3) = 2

我想出来了

function wrapIndex(i, i_max) {
        if(i > -1)
            return i%i_max;

        var x = i_max + i%i_max;
        if(x == i_max)
            return 0;

        return x;
    }

有没有更好的方法来做到这一点?

pol*_*nts 22

此解决方案是无分支的,但执行%两次:

function wrapIndex(i, i_max) {
   return ((i % i_max) + i_max) % i_max;
}
Run Code Online (Sandbox Code Playgroud)

应该说%假设C#/ Java行为,即结果与被除数具有相同的符号.有些语言定义余数计算来取代除数的符号(例如mod在Clojure中).有些语言有两种变体(mod/ remCommon Lisp中的/ pair,Haskell等).Algol-68 %x总是返回一个非负数.C++将其实现到C++ 11,现在根据被除数符号(几乎)完全指定余数的符号.

也可以看看


Ste*_*non 10

有两个%操作的解决方案可以工作,但在大多数硬件上大多数语言都有所加快(但也有例外):

int wrapIndex(int i, int i_max) {
    i = i%i_max;
    return i<0 ? i+i_max : i;
}
Run Code Online (Sandbox Code Playgroud)


Mac*_*ehl 5

尼尔是一个品味问题,但如何

var x = (i_max + i % i_max) % i_max;
Run Code Online (Sandbox Code Playgroud)