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

מתוך ויקיפדיה, האנציקלופדיה החופשית
קפיצה לניווט קפיצה לחיפוש

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

בהינתן שני מספרים שלמים 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.