Download Lecture 7

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Large numbers wikipedia , lookup

Location arithmetic wikipedia , lookup

List of first-order theories wikipedia , lookup

Wiles's proof of Fermat's Last Theorem wikipedia , lookup

List of prime numbers wikipedia , lookup

Elementary mathematics wikipedia , lookup

Addition wikipedia , lookup

Collatz conjecture wikipedia , lookup

Proofs of Fermat's little theorem wikipedia , lookup

Arithmetic wikipedia , lookup

Quadratic reciprocity wikipedia , lookup

Transcript
CS1260 Mathematics for Computer Science
Unit 4 Modular Arithmetic
Arithmetic Mod 7 Using A Clock Face.
0
1
6
5
2
3
4
To work out 2+3, we start at 2 and move 3 places forwards (clockwise) to reach 5: this is the
same answer as for integer arithmetic. We say 2 + 35 mod 7. By contrast, to calculate
6+4, we start at 6 and move 4 places forwards to reach 3, which is different from integer
arithmetic. We say 6 + 4 ≡3 mod 7. Note also that 8 ≡1 mod 7, to see this start at 0 and
move 8 places clockwise to arrive at 1. Similarly
7≡0 mod 7
8≡1 mod 7
9≡2 mod 7
11≡4 mod 7 12≡5 mod 7
13≡6 mod 7
10≡ mod 7
14≡ mod 7
and so on. Similarly to work out 4 – 6 we start at 4 and move 6 places backwards (anticlockwise) to reach 5. We say 4 – 6≡5 mod 7. Note also that –3 ≡4 mod 7; to see this start
at zero and move 3 places backwards (anti-clockwise) to reach 4. Similarly we can show that
–1≡6 mod 7
–4≡ mod 7
–2≡5 mod 7
–5≡2 mod 7
–3≡4 mod 7
–6≡1 mod 7
To work out 3*4 we start at 0 and move 3 places forward 4 times over to reach 3, then 6, then
2 and finally 5. We say 3*4≡5 mod 7. Similarly 6*5≡2 mod 7 (starting from zero, move 6
places clockwise 5 times over to reach 6, 5, 4, 3 and finally 2.
Applications of Modular Arithmetic
Modular arithmetic has many important applications in computer science and mathematics
for example hash tables, random number generators and error-detecting codes, error
correcting codes and cryptography. We shall see some simple examples of these in this unit
and later in the course.
A More Rigorous Definition of Modular Numbers
Let n (> 1) be a positive integer and let Z denote the set of integers. The set of integers mod
n, Zn, is the set of non-negative integers less than n, that is
Zn = {xZ0 ≤ z < n} = {0, 1, 2, ...., n–1}.
We can define addition, subtraction and multiplication in Zn as follows
a+b
© A Barnes 2006
=
remainder when integer a+b is divided by n
1
CS1260/Unit4
a–b
a*b
=
=
remainder when integer a–b is divided by n
remainder when integer a*b is divided by n
where the addition and multiplication on the right-hand sides are the normal integer
operations.
Thus the addition and multiplication 'tables' in Z5 are
+
0
1
2
3
4
|
|
|
|
|
|
0
0
1
2
3
4
1
1
2
3
4
0
2
2
3
4
0
1
3
3
4
0
1
2
4
4
0
1
2
3
*
0
1
2
3
4
|
|
|
|
|
|
0
0
0
0
0
0
1
0
1
2
3
4
2
0
2
4
1
3
3
0
3
1
4
2
4
0
4
3
2
1
*
0
1
2
3
4
5
|
|
|
|
|
|
|
0
0
0
0
0
0
0
1
0
1
2
3
4
5
2
0
2
4
0
2
4
3
0
3
0
3
0
3
4
0
4
2
0
4
2
and the addition and multiplication 'tables' in Z6 are
+
0
1
2
3
4
5
|
|
|
|
|
|
|
0
0
1
2
3
4
5
1
1
2
3
4
5
0
2
2
3
4
5
0
1
3
3
4
5
0
1
2
4
4
5
0
1
2
3
5
5
0
1
2
3
4
5
0
5
4
3
2
1
To distinguish arithmetic operations in Zn (that is arithmetic operations mod n) from normal
integer operations we use the notation
a + b
≡
c
mod n
a * b
≡
d
mod n
Most of the usual algebraic properties of integer addition and multiplication extend to
addition and multiplication mod n.
Commutative Laws: a + b ≡ b + a
mod n
Associative Laws:
(a + b) + c ≡ a + (b+c)
(a * b) * c ≡ a* (b* c)
Distributive Law:
a * (b + c) ≡ a*b + a*c
Zero:
a + 0 ≡ a
mod n
Unit:
a * 1 ≡ a
mod n
a * b ≡b * a
mod n
mod n
mod n
mod n
a * 0 ≡ 0
mod n
However note that sometimes the product of two non-zero values can produce a zero result:
2 * 3≡ 0
mod 6
and
3 * 4≡ 0
mod 6
This can happen whenever the modulus n is not prime. However when the modulus p is
prime we have the important cancellation property:
if a ≠ 0

a * b ≡ a *c mod p
b
≡ c mod p
Also when the modulus p is prime any non-zero value has an inverse mod p.

x Zp . x ≠ 0 y Zp . x*y ≡ 1 mod p
We write x-1 ≡ y mod p. Of course if y ≡ x-1 then x≡ y-1 or equivalently (x-1)-1≡ x.
It is easy to show that this inverse is unique, thus inZp every non-zero value has a unique
inverse. For small values of the prime p it is easy to find x–1 mod p by trial and error.
However for larger values a better method is to use Fermat's theorem below.
© A Barnes 2006
2
CS1260/Unit4
Note that, in modular arithmetic. we do NOT usually write 1/4, but instead 4–1. Also instead
of dividing by one modular number (a, say) by another (b, say) we normally write a*b–1
rather than a/b.
Fermat's Little Theorem states that if p is prime and a ≠ 0 then
ap-1
thus
a-1
≡
≡
1
mod p
ap–2 mod p
For example
2-1
4-1
≡
≡
23
43
≡
≡
3
4
mod 5
mod 5
so that
so that
2*3
4*4
≡
≡
1
1
mod 5
mod 5
Example
Find the inverse of 5 mod 11.
Since 11 is a prime, the required inverse is 5(11–2) = 59 mod 11.
But 52 =25≡ 3 mod 11. Thus 54 = (52)2 ≡32≡ 9 mod 11.
Thus 58 =(54 )2≡92 = 81≡4 mod 11.
Finally 59 = 58 * 5≡ 4*5 = 20≡ mod 11
Thus 5–1≡9 mod 11.
Check 5*9 = 45≡1 mod 11
Note we can reduce intermediate results in a calculation to modular numbers to “stop
the numbers getting too large” or we can calculate a result using standard integer
arithmetic throughout and then reduce the result to a modular number at the end; the
end result is always the same.
Non-prime Moduli
If the modulus is not prime, some numbers have inverses and others do not. For example in
Z9, 2–1 5 mod 9 and 4–1  7 mod 9 and8–1  8 mod 9 , but neither 3 nor 6 have inverses
mod 9. We say the 3 and 6 are not invertible mod 9. In fact for any modulus n it can be
shown that a has an inverse mod n if and only if the greatest common divisor (gcd) of a and n
is unity (gcd(a, n) = 1). The greatest common divisor (gcd) of two integers a and b is the
largest positive number that divides (exactly without remainder) both a and b. Some books
use the term highest common factor (HCF) instead of greatest common divisor (GCD) – the
two terms are synonymous.
Examples
gcd(25, 45) = 5
since 25 = 5*5 and 45 =32*5.
gcd(78, 130) = 26 = 2*13
since 78 = 2*3*13 and 130 = 2*5*13.
Since 216 = 23 * 3 3 and 720 = 24 * 32 * 5 gcd(216, 720) = 23 * 32 = 72.
One common use of gcd is to reduce a fraction a/b to its lowest terms, by dividing numerator
and denominator by the gcd(a, b). For example, dividing the numerator 25 and denominator
45 of 25/45 by their gcd we get 25/45 = 5/9. Similarly as the gcd(78, 130) = 26, 78/130 =
3/5.
© A Barnes 2006
3
CS1260/Unit4
For non-prime moduli n, a generaliseation of Fermat's Little Theorem due to Euler is valid:
if gcd(a, n) = 1, then a is invertible mod n and
an ≡
1
a-1 ≡
an
mod n
thus
mod n
where (n) is Euler's phi-function which is defined by (n) = n (1 –1/p1) ...(1 –1/pm) and
where p1, ... pn are the prime factors of n. If gcd(a, n) ≠ 1, then a is not invertible mod n.
Example
Find the inverse of 5 mod 12.
Firstly we check that gcd(5, 12) = 1, so 5 is indeed invertible mod 12 and by Euler's theorem
5-1≡ 512 mod 12. Thus we need to calculate (12). But 12 = 22 * 3, thus
(12) = 12*(1 – 1/2)*(1 – 1/3) = 12* (1/2) * (2/3) = 4.
Thus 5-1≡ 512≡ 5(4-1)≡ 53 = 125≡ 5 mod 12.
Thus 5–1≡ 5 mod 12.
Check 5*5 = 25≡ 1 mod 12.
Java Integer Types as Modular Values
In Java the integer types byte, short, int and long are represented internally as twos
complement binary values with eight, sixteen, thirty-two and sixty-four bits respectively.
Thus their ranges are restricted as follows:
type
byte
short
int
long
minimum value
–27 = –128
–215 = –32768
–231 = –2147483648
–263
maximum value
27 – 1 = 127
215 – 1 = 32767
231 – 1 = 2147483647
263 – 1
and if an arithmetic operation overflows the allowed range it 'wraps' around. Thus adding one
to the largest byte value 127 wraps around to the smallest byte value –128 (since 8-bit twos
complement arithmetic is used). Other integer types behave similarly, for example adding 1
to the largest short value 32767 produces –32768. In passing we note that this 'wrap around'
behaviour has the unpleasant consequence that a loop of the form
for (byte i = 0; i<= 127; i++) {
......
}
is actually an infinite loop which never terminates! In some computing languages an
exception is thrown when arithmetic overflow occurs during a computation.
This wrap around behaviour is similar to that of modular numbers. In fact, if we interpret an
8-bit twos complement value as an unsigned 8-bit value then
–128
––>
128
–127
––>
129
–126
––>
130
..................
–3
––>
253
–2
––>
254
© A Barnes 2006
-128  128 mod 256
-127  129 mod 256
-12 6 130 mod 256
...................
-3  253 mod 256
-2  254 mod 256
4
CS1260/Unit4
–1
––>
-1  255
255
mod 256
Note also that twos complement addition is equivalent at bit level to unsigned binary
addition. Thus Java byte values behave internally exactly like integers mod 256 (=28)
except that values between 128 and 255 (inclusive) are displayed as their equivalent negative
forms (–128 to –1 inclusive). Similarly Java short values behave internally like integers mod
65556 (=216) and Java int values behave internally like integers mod 232.
Modular Numbers in Java
There is no direct support for modular arithmetic with general moduli in Java. However it is
relatively straightforward to implement a suitable class. Essentially we perform ordinary
integer arithmetic and then reduce the result to a modular number by using the Java remainder
operator %. However for negative values we need to correct the result of the remainder
operation by adding the modulus to get a positive result.
For example for Z7 we could write
public class Zn {
public static final short MODULUS = 7;
// say
// The MODULUS can be any integer n such that 2 ≤ n ≤ 32767 = 215–1
public final int val;
// always satisfies 0 ≤ val < MODULUS
public Zn(int n) {
n = n % MODULUS;
if (n < 0) {
// 'correct' for negative values
n = MODULUS + n;
}
val = n;
}
// addition
public static Zn add(Zn a, Zn b) {
return new Zn(a.val + b.val);
}
// unary minus
public static Zn minus(Zn a) {
return new Zn(-a.val);
}
// subtraction
public static Zn minus(Zn a, Zn b) {
return new Zn(a.val - b.val);
}
// multiplication
public static Zn times(Zn a, Zn b) {
return new Zn(a.val * b.val);
}
public String toString() {
return "" + val;
}
}
and we simply change the value of MODULUS in first line of the class for any other modulus.
In a client class we can then perform arithmetic as follows:
Zn a = new Zn(4);
Zn b = new Zn(6);
System.out.println(a + " + " + b + " mod 7 = " + Zn.add(a, b));
System.out.println(a + " - " + b + " mod 7 = " + Zn.minus(a, b));
© A Barnes 2006
5
CS1260/Unit4
System.out.println(a + " * " + b + " mod 7 = " + Zn.times(a, b));
Note that the modulus in the above code for class Zn is restricted to be of type short integer
(that is a16-bit integer) and, since values of the modulus which are negative or indeed ≤ 1, are
not meaningful, the modulus can be any integer in the range 2 to 215– 1 =32767 inclusive.
The reason for this choice is to avoid problems with integer overflow in arithmetic
operations. The val field, however, is declared to be of type int even though it can only ever
hold values in the range 0 ≤ val ≤ MODULUS. Thus arithmetic overflow is not possible
since the addition, subtraction or multiplcation of two int values in this range can never
produce a result outside the allowed range for int values namely –231 to 231 –1.
If we do wish to allow larger values of the modulus (in the range 2 to 231–1) then long (64bit) integer arithmetic must be used to avoid problems with overflow. In order to do this we
convert values to type long before performing any arithmetic and then conveert the result
back to type int before constructing the object representing the result. The necessary
changes are indicated in bold below. Use of the class by a client would be unaffected.
public class Zn {
public static final int MODULUS = 7;
// say
public final int val;
public Zn(int n) {
n = n % MODULUS;
if (n < 0) {
n = MODULUS + n;
}
val = n;
}
// addition
public static Zn add(Zn a, Zn b) {
long c = ((long) a.val + (long) b.val) % MODULUS;
return new Zn((int) c);
}
// unary minus
public static Zn minus(Zn a) {
return new Zn(-a.val);
}
// subtraction
public static Zn minus(Zn a, Zn b) {
long c = ((long) a.val - (long) b.val) % MODULUS;
return new Zn((int) c);
}
// multiplication
public static Zn times(Zn a, Zn b) {
long c = ((long) a.val * (long) b.val) % MODULUS;
return new Zn((int) c);
}
public String toString() {
return "" + val;
}
}
© A Barnes 2006
6
CS1260/Unit4