חילוק מודולרי

חילוק מודולרי הוא פעולת חילוק המתבצעת בין מספרים שלמים בחשבון מודולרי.

בהינתן שני מספרים שלמים a ו-b ומודולוס m, תוצאת החילוק המודולרי של a ב-b היא מספר z המקיים:

לדוגמה:

כי:

קיום ויחידותעריכה

בניגוד לשלוש פעולות החשבון האחרות, תוצאת החילוק המודולרי לא תמיד קיימת. לדוגמה, המספר:   אינו קיים, כי אין מספר שלם z כך ש:  .

תנאי הכרחי ומספיק לכך שהתוצאה תתקיים היא, שהמחלק המשותף המקסימלי (מחלק משותף גדול ביותר, או בקיצור, ממג"ב) של b, m מחלק את a:

 

בדוגמה למעלה, הממג"ב של 8 ו-2 הוא 2, והמחולק 1 אינו מתחלק ב-2, ולכן תוצאת החילוק אינה קיימת.


בניגוד לשלוש פעולות החשבון האחרות, תוצאת החילוק המודולרי אינה בהכרח יחידה. לדוגמה:

 

אבל גם:

 

כי:

 

באופן כללי, אם:

 

אז לכל מספר שלם k:

 

כי לכל k:

 

תוצאת החילוק היא יחידה מודולו המספר:

 .

חישובעריכה

ניתן לחשב חילוק מודולרי על ידי חישוב הופכי כפלי מודולרי של המחלק b, אם הוא קיים. בפרט, אם   הוא ההופכי הכפלי המודולרי של b מודולו m, אז על-פי ההגדרה:

 
 

ומכאן אפשר לחשב את z (תוצאת החילוק של a ב-b):

 

אולם, ישנם מקרים שבהם ההופכי הכפלי המודולרי אינו קיים - כאשר ל-b ול-m ישנו מחלק משותף גדול מ-1 (ראו הופכי כפלי מודולרי), ועדיין ניתן לבצע חילוק. לפיכך טוב יותר לבצע חילוק ישירות בעזרת אלגוריתם אוקלידס המורחב. אלגוריתם זה מוצא את הממג"ב של שני מספרים נתונים (במקרה זה: b ו-m), ובנוסף לכך מחשב שני מספרים x, y המקיימים את המשוואה:

 

כאמור בסעיף הקודם, ניתן לבצע את החילוק אם ורק אם a הוא כפולה שלמה של gcd(b,m), כלומר, כאשר קיים מספר שלם q המקיים:

 

במקרה זה ניתן להכפיל את המשוואה הקודמת ב-q ולקבל:

 

מכאן, על-פי הגדרת החשבון המודולרי:

 

ומכאן ש- qx הוא תוצאת החילוק.

לפניכם מימוש מעשי של האלגוריתם בשפת C++:[1]

/**
 * Euclid's extended algorithm:
 * Given a,b, Find gcd,x,y that solve the equation:
 *  ax + by = gcd(a,b)
 * @see http://en.wikipedia.org/wiki/Modular_multiplicative_inverse#Computation
 */
void xgcd (int a, int b,
	int& gcd, int& x, int& y) {
	x=0, y=1; 
	int u=1, v=0, m, n, q, r;
	gcd = b;
	while (a!=0) {
		q=gcd/a; r=gcd%a;
		m=x-u*q; n=y-v*q;
		gcd=a; a=r; x=u; y=v; u=m; v=n;
	}
}


/**
 * Modular division:
 * @return integer z such that: z * B mod m == A.
 * If there is more than one (i.e. when gcd(B,m)>1) - returns the smallest such integer
 */
int divide (int A, int B, int m) {
	assert (0 <= A && A<m);
	assert (0 <= B && B<m);

	int gcd, x, y;
	xgcd (B, m, gcd, x, y);  // x B + y m = gcd(B,m)
	if (A%gcd == 0) {        
		int q = A / gcd;       // x q B + y q m = m gcd = A
		return ((x + m)*q) % (m/gcd);   // Return the smallest result possible
	} else {
		throw "no quotient";
	}
}

ראו גםעריכה

קישורים חיצונייםעריכה

הערות שולייםעריכה

  1. ^ מסתמך על מימוש בשפת פייתון בדף en:Modular multiplicative inverse.