Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simplify modulus arithmetic?

I have

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

But that's a piece of garbage function. Help.

x is never going to be negative.


Here's a sort of Table of Truth, or something.

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

I'm trying to find some correlations here, but it's late and I don't think my brain is working correctly. zzz

What I'm seeing in the f(x) column is a sort of reverse modulus, whereby the outputs cycle from 032103210... instead of 01230123...

I'm sensing some use of Math.max or Math.min in combination with Math.abs might help … There's probably an x * -1 in there somewhere too …

Can you help me write f such that it doesn't suck so badly ?

like image 449
Mulan Avatar asked Sep 07 '16 06:09

Mulan


People also ask

What is the arithmetic operator for modulus?

The modulo operator, denoted by %, is an arithmetic operator. The modulo division operator produces the remainder of an integer division. produces the remainder when x is divided by y.

How do you explain modular arithmetic?

Modular arithmetic is a system of arithmetic for integers, which considers the remainder. In modular arithmetic, numbers "wrap around" upon reaching a given fixed quantity (this given quantity is known as the modulus) to leave a remainder.

What is the easiest way to understand modular arithmetic?

The easiest way to understand modular arithmetic is to think of it as finding the remainder of a number upon division by another number. For example, since both 15 and -9 leave the same remainder 3 when divided by 12, we say that

How do you use modular arithmetic in 5 hour clock?

An intuitive usage of modular arithmetic is with a 12-hour clock. If it is 10:00 now, then in 5 hours the clock will show 3:00 instead of 15:00. 3 is the remainder of 15 with a modulus of 12. N N. Two integers N N. In such a case, we say that a ≡ b ( m o d N). a \equiv b\pmod N. a≡ b (mod N).

What is the difference between modular addition and modular division?

Modular division is totally different from modular addition, subtraction and multiplication. It also does not exist always. (a / b) mod m is not equal to ( (a mod m) / (b mod m)) mod m. The modular inverse of a mod m exists only if a and m are relatively prime i.e. gcd (a, m) = 1. if (a x b) mod m = 1 then b is modular inverse of a.

How do you find the remainder of a modular number?

N N. In such a case, we say that a ≡ b ( m o d N). a \equiv b\pmod N. a≡ b (mod N). The easiest way to understand modular arithmetic is to think of it as finding the remainder of a number upon division by another number.


2 Answers

Moving Redu's use of bitwise operators a bit ahead:

f(x) = -x & 3

Table of Truths™

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

Original solution with negative value and a negative offset of 3 then modulo and add the same offset again.

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; }
like image 134
Nina Scholz Avatar answered Sep 29 '22 04:09

Nina Scholz


I thought you don't want to use modulo. Then here is your code.

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

Explanation: I just had to recall the back old days of truth tables which helped me to solve out this problem. So now we have inputs and output. Since we work in modulo 4 we are interested only in the last two bits.

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

So if we look, the output 2^1 digit is XOR of input 2^0 and 2^1 hence 2 * (x & 2 ? ~x & 1 : x & 1) and the output 2^0 digit is in fact input 2^0 digit. Which is (x & 1) hence... var f = x => 2 * (x & 2 ? ~x & 1 : x & 1) + (x & 1)

Note: (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
like image 44
Redu Avatar answered Sep 29 '22 06:09

Redu