负数的模负数

2023-09-11 02:22:49 作者:大无畏的奉献精神!

可能重复:   负号mod正在融化我的大脑!

Possible Duplicate: Mod of negative number is melting my brain!

我在想,如果有什么我试图做一个更好的算法:

I was wondering if there was a nicer algorithm for what I'm trying to do:


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;
    }

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

Is there a nicer way to do this?

推荐答案

这个解决方案是网点,但执行两次:

This solution is branchless, but performs % twice:

function wrapIndex(i, i_max) {
   return ((i % i_max) + i_max) % i_max;
}

应该说,假设的C#/ Java的行为,即结果具有相同的符号的分红的。有些语言定义剩余计算采取的除数的符号的替代(如 MOD Clojure中)。有些语言有两种变体( MOD / REM 对Common Lisp中,哈斯克尔等)。大陵68具有%X 它总是返回一个非负数。 C ++离开它到实施直到C ++ 11,现在剩余的标志是(几乎是)完全按照股息标志的规定。

It should be said the C#/Java behavior of % is assumed, i.e. the result has the same sign as the dividend. Some languages define the remainder calculation to take the sign of the divisor instead (e.g. mod in Clojure). Some languages have both variants (mod/rem pair in Common Lisp, Haskell, etc). Algol-68 has %x which always returns a non-negative number. C++ left it up to implementation until C++11, now the sign of the remainder is (almost) fully specified according to the dividend sign.

维基/模操作