* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Lecture 7
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
Collatz conjecture wikipedia , lookup
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 + 35 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 = {xZ0 ≤ 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 inZp 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 and8–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 an ≡ 1 a-1 ≡ an 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≡ 512 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≡ 512≡ 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