我想知道我尝试做的算法是否更好:
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
我想出了
函数wrapIndex(i,i_max){ 如果(i> -1) 返回i%i_max; var x = i_max + i%i_max; 如果(x == i_max) 返回0; 返回x; }
有没有更好的方法可以做到这一点?
该解决方案是无分支的,但是执行%两次:
%
function wrapIndex(i, i_max) { return ((i % i_max) + i_max) % i_max; }
应该说%是假设了C#/ Java的行为,即结果与 _被除数_具有相同的符号。一些语言将余数计算定义为取 _除数_的符号(例如,mod在Clojure中)。某些语言有两种变体(Common Lisp,Haskell等中的mod/ rempair)。Algol-68 %x始终返回非负数。C 直到C 11才实施。
mod
rem
%x