Two's complement and 2-adic number
This posts discusses the relation between two's complement and 2-adic integer in math. I want to show what operations we can have if we ignore overflow.
-adic number
The p-adic number system is a different extension to the rational number field . Consider the -radix representation of a fraction. Say in decimal:
This is a power series of . Here we use . If we accept all possible power series:
we get the real number . (Well, more strictly we need to make )
However, we can also expand the same number in power series of :
If we accept all possible power series:
we get 10-adic numbers. This series does not converge under normal metric, but if we define a new metric with not divisible by , such power series converge. Typically we only use prime , so a -adic number is represented in a reverse -base numeral system, where one can have infinite digits above the decimal point but finitely many after. It is a field of characteristic , denoted by . If we limit ourselves to those numbers without minus powers of , i.e. without digits after decimal point, we have -adic integer . Formally, we define it as the inverse limit , with projection . That is, the limit of finite ring when . In a computer, we use finitely many bits to store an integer (). Imagine that if we extend it to infinitely many bits, we get -adic number .
Basic Operations
Addition & Subtraction
The normal integer embeds in . More specifically, we have
Thus, is equal to , i.e. the binary complement of . This is exactly how we represent negative integers in 2's complement: take complement and add one. In this sense, we can take 2's complement representation as the last bits of 2-adic representation.
2-adic representation works for every number in 2-adic ring.
The same bit-by-bit addition and subtraction algorithm works for both positive and negative numbers.
Therefore, 2's complement is in the same situation:
signed and unsigned integers are only about how humans interpret it;
there is no need to separate them when we perform operations.
That's why in x86 assembly we only have ADD/ADC
and SUB/SBB
.
But when we convert an integer of a small word size to a wider word,
we do need to tell whether it's negative or not.
For negative integers, we fill in higher bits with 1; for positive, 0.
Therefore, in x86 we have different instructions to extend an integer:
Sign extension CBW/CWDE/CDQE/MOVSX/MOVSXD
for signed integers; zero extension MOVZX
for unsigned integers.
Multiplication & Euclidean Division
Since 2-adic ring is closed under multiplication, the 2-adic representation works for both positive and negative.
Therefore, signed and unsigned multiplication are the same.
In x86 assembly we have IMUL
vs MUL
, but this is simply because x86 multiplication extends the result to a longer word.
If we ignore the extended part:
which shows that modulo is the product of each modulo .
However, Euclidean division is a different story, because 2-adic numbers do not support comparison. For example, if we divide -bit by , we get with . But if we divide by , we get with remainder .
Inversion
In 2-adic number ring, any number not divisible by 2 has a unique multiplicative inverse. For example,
This also works in finite word length if we multiply with overflow.
For example, in -bit integer,
is truncated to ,
and we have (-1527099483) * 45 == 1
in C++ int
.
Note that the binary fraction form of is
So the "flip and add one" rule somehow applies here.
Multiplicative Group
An interesting fact is the multiplicative group of is , which contains itself as a component.
To show this, let and being the projection modulo . The kernal of this projection is . Clearly, we have since every odd number is invertible. Also, the map defines an isomorphism , because
Now, define be . Note that:
is of order . In this group we have and . Thus, is cyclic and generated by . Take the inverse limit and get
On the other hand, with . Thus, every invertible element can be written as , where and or .
Now let's move to the finite case . We know that () has a primitive root if and only if is an odd prime. From the argument above, we further learn that the multiplicative group of is actually of form or simply , when .
Square numbers
Every is a square number if and only if is even and is a square number. By the analysis above, the latter one is equivalent to . The same condition applies to finite ring .
Note that this shows that every square number in has four square roots. For example, the square roots of are , with two of them divisible by . For 32-bit unsigned int, they are , which is exactly as a signed int.
This does not give any contradiction to the theorem that a polynomial of degree over a domain (e.g. ) can have at most distinct roots. Because the two non-trivial roots of in are , which cannot be lifted to a real solution in .
Hilbert symbol
Define the Hilbert symbol to be if has a non-trivial solution, and otherwise. Let . Then, is a bilinear form on . Under basis , its matrix is . The proof is omitted as it contains a lot of computation.
References
- Serre, J.-P. (1973). A course in arithmetic. Springer.