רוצים לחלק באפס? אין בעיה! (אין כלום, בעצם)

אני עוקב פה ושם אחרי המטורפים שאיתם נאלץ מרק, הכותב המסכן של Good math, bad math להתמודד. הפעם  הוא נאבק בברנש שעוסק בחלוקה באפס - “First off, 1/0 is infinity”. כפי שמרק אומר בבלוג, כבר כאן צריך לקטוע את הברנש עם “בזזזט. שגוי”, כי אחד חלקי אפס כלל איננו מספר; המשמעות של “אחד חלקי איקס” היא מספר שכאשר הוא מוכפל באיקס, מקבלים אחד; אבל מכיוון שכל דבר כפול אפס נותן אפס, בוודאי שלא קיים מספר שכזה. דא עקא, ההסבר הזה מותיר פתח לשאלה “אוקיי, אז מה עם 0/0?” והברנש הזכיר לי בפתיחת המכתב שלו (“I was searching the internet for stuff on Nullity, this new number that I noticed you think is crank.”) את אחת הפרשיות התמוהות ביותר מהעת האחרונה (כבר מ-2006, אמנם) שעוסקת בביטוי הלא מוגדר האומלל הזה - פרשיית “Nullity” (שאתרגם בצורה חופשית ביותר כ”כלומיתי”). זוהי פרשיית טרחן כפייתי “מודרנית” קלאסית - הטרחן הוא ללא ספק טרחן, אבל הוא היה נותר בגדר טמבל לא מזיק (הרעיונות שלו, שאציג בהמשך, אינם מופרכים או שגויים מהותית; הטרחנות שלו מתבטאת בחשיבה השגויה שהוא גילה את אמריקה) אלמלא היה זוכה לכיסוי תקשורתי מיותר, הפעם של ה-BBC.

ראשית כל, אין מנוס מלתאר מה באמת עושים במתמטיקה בנוגע לכל העסק המלוכלך הזה של חלוקה באפס, מה שידרוש את הפוסט כולו. השאלה המהותית שצריכה להישאל היא לא “האם אפשר לחלק באפס”, כי תמיד אפשר להגדיר את החלוקה באיזו דרך שרוצים; אלא “למה לנו לחלק באפס”, כלומר מה המשמעות שאנו בוחרים לייחס למושג החלוקה, והאם הצורה שבה נגדיר את החלוקה באפס מסתדרת עם המשמעות הזו. מתמטיקה ללא משמעות - אוסף של סמלים וכללים למניפולציה שלהם ותו לא - היא, ובכן, חסרת משמעות.

נניח, אם כן, שכבר בנינו את המספרים השלמים - אחד, שתיים, שלוש וכן הלאה (המספרים הטבעיים), אפס (המספר הבעייתי) וכמו כן מינוס אחד, מינוס שתיים, מינוס שלוש וכן הלאה (המספרים השליליים). הגדרנו עליהם פעולות חיבור וכפל במובן הרגיל. שימו לב לכך ש”לחסר חמש משמונה” הוא בעצם “לחבר מינוס חמש עם שמונה” - כלומר, אין לנו צורך להגדיר פעולה חדשה של “חיסור” - אנחנו מתבססים על פעולת החיבור הקיימת, ועל המספרים השליליים שהוספנו למערכת, כש”מינוס שמונה” מוגדר בתור “המספר שכאשר מחברים אותו עם שמונה מקבלים אפס” - החשיבות של אפס כאן היא הנייטרליות שלו ביחס לפעולת החיבור: כל מספר ועוד אפס הוא המספר עצמו.

את כל זה כבר תיארתי בשעתו כשתיארתי איך בונים את המספרים השליליים. המוטיבציה המיידית שלנו להמשיך ולהרחיב את מערכת המספרים היא פתרון משוואות מהצורה \( ax=b \), שמאלצות אותנו להשתמש בפעולה שבבית הספר אנו קוראים לה “חילוק”. לפעמים הן ניתנות לפתרון (נניח, \( 3x=18 \)) אבל לא תמיד (נניח \( 3x=16 \)), כלומר החילוק במתכונתו הנוכחית בכלל לא מוגדר היטב ברוב המקרים. לכן אנחנו רוצים להוסיף למערכת שלנו כמה שיותר מספרים “חלקיים” שיאפשרו לנו להגדיר חילוק לכל איבר. הדרך לעשות זאת אנלוגית לדרך שבה יוצרים מספרים שליליים: לכל מספר \( a \) מוסיפים מספר \( \frac{1}{a} \) (זהו ממש הסימון שלו - סימון מקובל אחר הוא \( a^{-1} \)) כך שמכפלתם היא 1; והסיבה שבחרנו דווקא ב-1 היא ש-1 הוא נייטרלי לכפל, בדומה לכך ש-0 הוא נייטרלי לחיבור. למספר הזה קוראים “ההופכי של \( a \)), והוא פותר את המשוואה \( ax=1 \). כעת אפשר להגדיר חילוק באופן כללי על ידי כפל בהופכי, והפתרון של המשוואה הכללית \( ax=b \) יהיה “ההופכי של a כפול b” וחסל.

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

\( a(b+c)=ab+ac \)

ישתמרו גם כשמציבים בתור a,b,c מספרים “הופכיים” שכאלה. תכף ומייד מתברר לנו שאם יש לאפס הופכי ואנו רוצים שהכללים הללו ימשיכו להתקיים, צפוי לנו אסון נורא:

\( a\cdot 0=a\cdot (0+0)=a\cdot 0+a\cdot 0 \)

ומכאן נובע באמצעות העברת אגפים:

\( a\cdot 0=0 \) לכל a שרק תרצו. בפרט עבור \( a=0^{-1} \). אבל הרי על פי הגדרתו, \( 0^{-1}\cdot 0=1 \), ולכן קיבלנו את המשוואה החביבה 0=1, שבצעד אחד נוסף מוכיחה לנו שכל מספר שווה לאפס (איך?)

אאוץ’. הלכה מערכת המספרים. מסקנה: אם מוסיפים הופכי לאפס, חלק מכללי החיבור והכפל כבר לא יחולו עליו (לעומת זאת, ניתן להוכיח שעבור כל שאר ההופכיים לא יווצרו בעיות שכאלו).

כלומר, במובן הרגיל של חילוק, אין משמעות לחילוק באפס - לא נקבל מספר. אלא מה, זה משאיר אותנו עם פעולה שמוגדרת כמעט לכל מספר, אבל אם ננסה להפעיל אותה על 0, נתרסק. בפרט, תוכנות מחשב רבות אכן קורסות כאשר מבצעים בהן חלוקה באפס. האם אין דרך יותר טובה להתמודד עם זה? האם לא ניתן לתת לחלוקה באפס משמעות, אמנם לא בדמות מספר שמקיים את כללי הכפל והחיבור הרגילים?

ובכן, לפעמים יש טעם לדבר על חלוקה לא באפס, אלא במספרים שהם קטנים מאוד, “כמעט” אפס, ובהתבוננות בצורה שבה התוצאה משתנה ככל שמה שמחלקים בו נהיה קטן יותר. זה בדיוק מה שהחשבון האינפיניטסימלי עוסק בו. נתבונן למשל בפונקציה \( f(x)=\frac{1}{x} \). עבור אפס היא כלל לא מוגדרת, אבל לא קשה לראות שככל שמכניסים לתוכה ערכים חיוביים של איקס שהולכים וקרבים לאפס, מקבלים תוצאה חיובית גדולה יותר ויותר. על זה אומרים ש”הפונקציה שואפת לאינסוף כאשר איקס שואף לאפס מימין” - מימין מציין כאן את העובדה שאנו מזינים לפונקציה ערכים חיוביים, כלומר מצד ימין של ציר המספרים; אם איקס ישאף לאפס משמאל, נקבל ערכים ששואפים למינוס אינסוף. לכן קשה להגיד ש”אחד חלקי אפס הוא אינסוף”, כי באותה המידה הוא יכול להיות גם מינוס אינסוף; אבל לפעמים אין הבדל בין שני המקרים בכל הנוגע למה שמעניין אותנו.

דוגמה קלאסית, ואפילו פרקטית (אם כי לרוב הדרכים הפרקטיות באמת להתגבר עליה הן לעקוף אותה - לא ניכנס לכך כאן) צצה בגאומטריה האנליטית, שבה מייצגים ישרים באמצעות משוואות מהצורה \( y=mx+n \). הקבוע \( m \) מכונה ”השיפוע” של הישר, וככל שהוא גדול יותר, כך הקו נוטה יותר להיות אנכי (שיפוע 0 פירושו קו אופקי לגמרי). אם יש שתי נקודות שונות זו מזו שדרכן הקו עובר, \( (x_1,y_1),(x_2,y_2) \) אז השיפוע ניתן לחישוב באמצעות \( m=\frac{y_2-y_1}{x_2-x_1} \). קל לראות שבמשוואה הזו עלולים לקבל חלוקה באפס, אם שתי קוארדינטות האיקס זהות; במקרה הזה פירוש הדבר הוא שהקו הוא אנכי לחלוטין - השיפוע שלו הוא “אינסוף”, והמשוואה שמתארת אותו היא בכלל מהצורה \( x=n \) (כלומר, כל נקודה שעל הקו היא בעלת אותה קוארדינטת x). הוספת אינסוף למערכת המספרים שלנו בתור תיאור של שיפוע הישר עוזרת לנו לתת משמעות כלשהי לשיפוע שלו גם במקרה של ישר אנכי; אבל מבחינה תכנותית, עדיין נצטרך לטפל במקרה הזה בנפרד. בפרט, עדיין תהיה לנו בעיה אם תבוצע חלוקה באפס כשאנחנו “לא מוכנים להתמודד איתה”.

חייבים לשים לב לכך שה”אינסוף” הזה שהצענו איננו ההופכי של 0; אחרת, למשל, אפשר לקבל ש-1=2, כי \( \frac{1}{0}=\infty=\frac{2}{0} \) ועכשיו כפלו באפס את כל האגפים. מכאן שצריך להיות מאוד זהירים בכל הנוגע למה שקורה עם האינסוף - לרוב גם תוכנות מתמטיקה (דוגמת Matlab) שטורחות להגדיר את אחד חלקי אפס בתור “Inf” (קיצור של Infinity) משאירות את Inf כפול אפס בתור “NaN” (קיצור של Not a number). ה-NaN הזה הוא הסימול שנקבע בסטנדרט לייצוג במחשב של “תוצאה לא מוגדרת”. עוד דרכים שבהן NaN עשוי להתקבל הן כתוצאה מכל מני פעולות אחרות על Inf - למשל, לחבר אותו עם מינוס עצמו, לחלק אותו בעצמו, וכדומה. ועוד חלוקה אחת שמובילה אוטומטית ל-NaN היא 0/0, חלוקה של אפס בעצמו. מה שמחזיר אותנו שוב לשאלה “למה לא להגדיר את זה כאפס וזהו?”. התשובה הקצרה היא שמנקודת מבטו של החשבון האינפיניטסימלי (שנתן לנו את המוטיבציה הראשונית להכניס את האינסוף למשחק בכלל) פונקציות שכאשר איקס שואף לאפס הן שואפות לביטוי בצורה אפס חלקי אפס יכולות לשאוף לכל מספר אפשרי. הדוגמה הפשוטה ביותר היא \( f(x)=\frac{ax}{x} \) כאשר a הוא מספר כלשהו. כאשר איקס שואף לאפס הפונקציה תשאף ל-\( a \), ועם זאת היא שואפת לביטוי \( \frac{0}{0} \).

כדי להשתכנע שגם מנקודת מבט “אלגברית” אין טעם בלהגדיר את 0/0 בתור 0, תחשבו עוד פעם על דוגמת הגאומטריה האנליטית. אם בטעות הזנתם את אותה נקודה פעמיים ואתם מנסים להפיק ממנה את שיפוע הישר, ואם משום מה לא ביצעתם בדיקה האם באמת הוזנה אותה הנקודה פעמיים, ואם משום מה אצלכם 0/0 כן מוגדר בתור 0, אז הפונקציה תטען ששיפוע הישר הוא 0 - תוצאה חסרת הגיון ומשמעות לגמרי. כבר עדיף לקבל כאן שגיאה מאשר לחשוב שהכל כרגיל ולהמשיך את הריצה עד שמגיעים לשלב שבו משתמשים בישר בעל השיפוע הלא קשור בעליל ואז באמת הכל מתרסק.

אם כן, תשאלו, מה הטעם בלתת ל-0/0 שם מפוצץ כמו “NaN”? הסיבה הפשוטה היא ש-NaN הוא סמל שהמחשב יודע לזהות ולעבוד איתו, ובפרט אפשר גם לבדוק בכל שלב אם תוצאת החישוב שלנו היא NaN או לא - ואם היא כן, להבין שמשהו השתבש ולנסות לתקן. הגיוני לצפות שבשלב שבו בוצע חישוב שתוצאתו הייתה NaN התוכנה גם תשלח אזהרה כללית, באמצעות מנגנון החריגות (Exceptions) שכל שפת תכנות מודרנית תומכת בו; אבל לא תמיד זה נוח (נניח, אם אתם מפעילים פונקציה על אלפי איברים ברצף ועבור חלק קטן מהם היא תיכשל, לא תרצו שבכל פעם שיש בעיה תצטרכו לקטוע את רצף החישוב ולטפל בחריגה - כבר יותר נוח לתת למחשב לשים את הערך NaN בתור התוצאה במקרים הללו, ואחר כך לסנן את הערכים הללו).

וכעת ניתן לחזור לטרחן הכפייתי שלנו, אחרי שהצלחתי (אני מקווה) לשכנע אתכם שבימינו אף אחד כבר לא מתרגש מחלוקה באפס, ויש הגדרות סטנדרטיות ומקובלות לתוצאה של חלוקה כזו, גם מנקודת מבט תכנותית. מה שעולל הטרחן שלנו הוא להתעלם מכל זה, להמציא מחדש את גלגל ה-NaN בלבוש פומפוזי יותר, ולטעון שבכך הוא “פתר בעייה בת 1,200 שנים”. לברנש קוראים ד”ר ג’יימס אנדרסון, ועל התגלית שלו אפשר לקרוא כאן. עם זאת, בדרך כלל המקום הטוב ביותר לקרוא על טרחנים הוא מפיהם עצמם - הנה מצגת שהוא עומד מאחוריה, ככל הנראה, והנה מאמר שמפרט קצת יותר את מה שהוא עשה. כדי להפריד בין המתמטיקה האמיתית (שאותה הצגתי, אם כי בצורה חלקית, בפוסט הזה) ובין השטויות, אדחה את העיסוק בתיאוריה שלו לפוסט הבא. לעת עתה, “טיזר” - כל מה שהגאון עושה הוא לתת ל-NaN שם אחר ולטעון שכעת זה “מספר”.


נהניתם? התעניינתם? אם תרצו, אתם מוזמנים לתת טיפ:

Buy Me a Coffee at ko-fi.com