עבור לתוכן
View in the app

A better way to browse. Learn more.

HWzone

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

בעיית דיוק מאוד מוזרה ב-Java (עם float)

Featured Replies

פורסם

שימו לב לקוד הפשוט הבא:

for (float k=0; k<=2; k+=0.1) {

System.out.print(k + " ");

}

ושימו לב לפלט:

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.70000005 0.8000001 0.9000001 1.0000001 1.1000001 1.2000002 1.3000002 1.4000002 1.5000002 1.6000003 1.7000003 1.8000003 1.9000003

מישהו מכיר את הבעיה? יודע איך פותרים אותה? יודע למה זה קורה??

פורסם

תנסה אולי לעבוד ב DOUBLE במקום FLOAT ?

פורסם

אני לא בטוח שזה יפתור את הבעיה.

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

מה שקורה הוא שנוצר אי דיוק שמצטבר (כלומר, k לא גדל בדיוק ב-0.1 כל פעם אלא במשהו כמו 0.100000002)

כשאי הדיוק קטן מספיק, ג'אווה מתעלם ממנו, אבל כשהוא מספיק גדול הוא מציג אותו.

יש כמה פתרונות:

1. לא להשתמש בשברים, אלא להגדיר i שלם שירוץ מ-0 עד 20, ובתוך הלולאה להגדיר k=(float)i/10

2. כל פעם לעגל את k לכפולה של 0.1 (אני לא בטוח שג'אווה מאפשר את זה בצורה טריוויאלית, כי הפונקציה round מעגלת רק לשלמים)

3. אני מניח שאפשר לגרום לו להדפיס ברמת דיוק יותר נמוכה (ואז 0.9000001 יהפוך ל-0.9), אבל אז k עדיין לא יהיה מדויק.

פורסם
  • מחבר

ב-double יש את אותה הבעיה.

ועוד יותר מוזר, החישוב של 0.6+0.1 עדיין נותן תוצאה לא מדוייקת...

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

תודה בכל מקרה.

פורסם

לעבוד עם float/double זה אומר בהכרח להתמודד עם שגיאות דיוק.

אתה לא אמור להשוות בין שני floats/double בשום מקרה ע"י '=' אלא ע"י abs(x-y)<eps

(כאשר eps הוא איזשהו מספר קטן מאוד)

הפיתרון הראשון שהוצע נשמע לי הכי הגיוני (כי השגיאה בו לא מצטברת).

פורסם

איכסה אפסילון.

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

דיונים חדשים

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.