• בלוג
  • למה קשה לחשב שברים

למה קשה לחשב שברים

09/01/2025

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

1. איך מחשבים שברים

כל שפת תכנות כולל הישנות יודעת לבצע חישובים. לדוגמה בשפת פייתון אנחנו יכולים לכתוב את הקוד הבא כדי להדפיס את המכפלה של 2 ו-3 ולקבל על המסך 6:

x = 3
y = 2
print(x * y)

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

x = 0.1
y = 0.2
print(x + y)

אני אקבל את התוצאה:

0.30000000000000004

ולא את 0.3 כמו שאולי אפשר היה לצפות. או בדוגמה נוספת:

>>> 2 - 1.1
0.8999999999999999

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

2. מה עושים עם הכסף

אחד המקומות בהם טעות זו יכולה להיות הכי מרגיזה הוא בעבודה עם כסף. ברור שאם מישהו קונה מוצר שעולה 2 ש"ח ומשלם שקל ועשר אגורות אנחנו צריכים להחזיר לו 90 אגורות, אפילו שהתרגיל בתוכנית המחשב לא משקף את זה.

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

>>> 200 - 110
90

וכולם מבינים פה שצריך להחזיר 90 אגורות.

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

  1. עליהם למצוא את כל המידע בבסיס הנתונים ששמור בפורמט שהם יצרו ולעדכן את הפורמט ל-3 ספרות אחרי הנקודה העשרונית.

  2. עליהם למצוא את כל המקומות בקוד בהם מוגדרים מספרים בפורמט הזה ולתקן ל-3 ספרות.

  3. עליהם למצוא את כל קטעי הקוד שקוראים מידע או כותבים אותו ולתקן אותם כדי לכפול באלף במקום במאה.

וכן זה המון עבודה ובמערכות ישנות גם פוטנציאל גבוה לטעויות.

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

from decimal import *

>>> Decimal('0.1') + Decimal('0.2')
Decimal('0.3')

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