如何简化模运算?

How to simplify modulus arithmetic?

我有

let f = x => x % 4 === 0 ? 0 : 4 - x % 4

但这是一个垃圾函数。帮助。

x 永远不会是负数。


这是一种 Table 的真理之类的东西。

x   x % 4     4 - (x % 4)     f(x)
0   0         4               0
1   1         3               3
2   2         2               2
3   3         1               1
4   0         4               0
5   1         3               3
6   2         2               2
7   3         1               1
8   0         4               0
9   1         3               3

我想在这里找到一些相关性,但已经晚了,我认为我的大脑工作不正常。 zzz

我在 f(x) 列中看到的是一种 反向模数 ,输出循环从 032103210... 而不是 01230123...

我感觉 Math.maxMath.minMath.abs 结合使用可能会有所帮助……那里的某个地方可能也有一个 x * -1 ……

你能帮我写 f 这样它就不会那么糟糕吗?

这样的事情肯定会做:

(4 - (x % 4)) % 4

这里有更多真相:

x   x % 4     4 - (x % 4)     (4 - (x % 4)) % 4
0   0         4               0
1   1         3               3
2   2         2               2
3   3         1               1
4   0         4               0
5   1         3               3
6   2         2               2
7   3         1               1
8   0         4               0
9   1         3               3

将 Redu 的 向前移动一点:

f(x) = -x & 3

Table 真理™

x       x       -x       3    -x&3    -x&3
-    ----    -----    ----    ----    ----
0    0000     0000    0011    0000       0
1    0001    -0001    0011    0011       3
2    0010    -0010    0011    0010       2
3    0011    -0011    0011    0001       1
4    0100    -0100    0011    0000       0
5    0101    -0101    0011    0011       3
6    0110    -0110    0011    0010       2
7    0111    -0111    0011    0001       1
8    1000    -1000    0011    0000       0
9    1001    -1001    0011    0011       3

var i, 
    f = x => -x & 3;

for (i = 0; i < 20; i++) {
    console.log(i, f(i));
}
.as-console-wrapper { max-height: 100% !important; top: 0; }

具有负值和负偏移量 3 的原始解,然后取模并再次添加相同的偏移量。

f(x) = (-x - 3) % 4 + 3

var i, 
    f = x => (-x - 3) % 4 + 3;

for (i = 0; i < 20; i++) {
    console.log(i, f(i));
}
.as-console-wrapper { max-height: 100% !important; top: 0; }

我以为你不想使用模数。那么这是你的代码。

var f = x => 2 * (x & 2 ? ~x & 1 : x & 1) + (x & 1)

x   x % 4    4 - (x % 4)       f(x)
0     0         4               0
1     1         3               3
2     2         2               2
3     3         1               1
4     0         4               0
5     1         3               3
6     2         2               2
7     3         1               1
8     0         4               0
9     1         3               3

解释:我只需要回想一下过去帮助我解决这个问题的真值表。所以现在我们有了输入和输出。由于我们以模 4 工作,因此我们只对最后两位感兴趣。

 Input    Output
0 : 0 0    0 0
1 : 0 1    1 1
2 : 1 0    1 0
3 : 1 1    0 1

所以如果我们看,输出 2^1 数字是输入 2^0 和 2^1 的异或,因此 2 * (x & 2 ? ~x & 1 : x & 1) 输出 2^0 数字实际上是输入 2^0 数字。这是 (x & 1) 因此... var f = x => 2 * (x & 2 ? ~x & 1 : x & 1) + (x & 1)

注:(foo XOR bar = foo ? !bar : bar)


                                 u       v
                        y        z       z       w
   x       x & 2   ?    ~x       y & 1   x & 1   2 * z  w + v  f(x)
-- ------  ------  ---  -------  ------  ------  -----  -----  ----
0  0000    0000    F    -0001    0001    0000    0      0      0
1  0001    0000    F    -0010    0000    0001    2      3      3
2  0010    0010    T    -0011    0001    0000    2      2      2
3  0011    0010    T    -0100    0000    0001    0      1      1
4  0100    0000    F    -0101    0001    0000    0      0      0
5  0101    0000    F    -0110    0000    0001    2      3      3
7  0110    0010    T    -0111    0001    0000    2      2      2
8  0111    0010    T    -1000    0000    0001    0      1      1
9  1000    0000    F    -1001    0001    0000    0      0      0