如何简化模运算?
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.max
或 Math.min
与 Math.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
我有
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.max
或 Math.min
与 Math.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