Arithmetic inequality comparison of integers in residues modulo primes

chinese remainder theoreminequalitymodular arithmetic

Consider arbitrary precision integers $a, b$ represented in residue form modulo a set of primes $\{ p_0, p_1, \dots, p_n \}$. We can represent very large integers by increasing the number of prime modulii. We can do addition, subtraction, multiplication of arbitrary precision integers efficiently in a modular number system.

Example: $P = \{2, 3, 5, 7\}, M = 2.3.5.7 = 210$. This modulii can represent integers upto 210. If we wanted to represent larger integers , we can add more primes to the set $P$.

The residue representation of $a = 25$ would be $\langle a_2, a_3, a_5, a_7 \rangle = \langle 1, 1, 0, 4 \rangle$.

The residue representation of $b = 29$ would be $\langle b_2, b_3, b_5, b_7 \rangle = \langle 1, 2, 4, 1 \rangle$.

This is calculated by taking residues of the number modulo the prime modulii.

This question is about performing arithmetic inequality comparisons in the modular residue number system.

Although in this example, it appears that we can do element-wise comparison (lexicographic comparison) of the residues for >, < operations, that will not work for general $a, b$ for the simple reason that the residue modulo a single prime does not tell you how large the actual number is.

If we want to do an arithmetic inequality comparison ($a < b, a > b$) of these residue representations correctly, one way to do that would be convert them back to arbitrary precision integers using Chinese Remainder Theorem (CRT) and then do the bitwise (or byte/word/digit-wise) comparison.

Are there any other ways or tricks to accomplish this without doing the CRT conversion?

Related:

GCD computation in Modular Residue Number System

Best Answer

In general, the residues number system (RNS) does not work with the negative numbers at all. On the other hand, if the modulus $\;M=m_1\times m_2\times\dots\times m_k\;$ of the certain RNS is even, $\;M=2H,\;$ and $\;H\;$ is odd, and the sign of an arbitrary integer number is defined as $$\text{sgn }^\,_M(n)=\begin{cases} -1,\; \text{ if } \;(n\mod M) \not= (n\mod \frac M2)\\ 0,\quad \text{ if } \;(n\mod M) = 0\\ 1,\quad \text{ otherwize }. \end{cases}$$ then the simple direct algorithm can be built.

Really, let $$\;n=\overline{n_1n_2\dots n_k}^\,_{(2\times m_2\times\dots\times m_k)},\;$$ then $$\;n\mod\frac M2=\overline{n_2\dots n_k}^\,_{(m_2\times\dots\times m_k)} = \overline{b_1n_2\dots n_k}^\,_{(2\times m_2\times\dots\times m_k)},\;$$

where $$b_1 = \overline{n_2\dots n_k}^\,_{(m_2\times\dots\times m_k)} \mod2 = \left(\sum_{j=2}^k (n_j\mod2) p_j\right) \mod2,\tag1$$ and $\;p_j\;$ are the predefined bit constants in the form of $$p_j =\overline{\delta_{2,j},\delta_{3,j},\dots \delta_{k,j}}^\,_{(m_2\times\dots\times m_k)}\mod2.\tag2$$ If the last bits of $\;n_2,n_3,\dots,n_k\;$ presented as the least bits of the int64 number B and the bits $\;p_j\;$ are similarly collected in the int64 mask P, then multiplication can be calculated in the form v= B & P, summation of bits as the C-code in the form of

v = v - ((v >> 1) & 0x5555555555555555);                        // sums in pairs of bits, g+l=(2g+l)-g  
v = (v & 0x3333333333333333) + ((v >> 2) & 0x3333333333333333); // sums in tetrades
c = (((v + (v >> 4)) & 0x0F0F0F0F0F0F0F0F) * 0x101010101010101) >> 56; // total sum

and the bit $b_1$ is the least signed bit of the number c.

Therefore:

  • if $b_1\not=n_1,$ then $n$ is negative, so on;
  • the expression $\;\text{ sgn }_M(a-b)\;$ defines the comparation results.
Related Question