שְׁאֵלָה:
באג כפל פשוט
Huskarnov
2019-02-05 15:36:59 UTC
view on stackexchange narkive permalink

ביצוע הקוד הבא תמיד נותן -511 כתוצאה מכך, ביצעתי בדיקות רבות ונראה שהתוצאות נכונות מ- 0 * 0 ל- 181 * 181, מעבר לכך, התוצאות אינן תקינות, ניסיתי סוגים רבים עבור ה- z משתנה (int, long, float) ללא הצלחה, רעיון כלשהו? אני משתמש ב- Arduino Uno.

  ארוך z = 0; הגדרת חלל () {Serial.begin (9600);} loop loop () {z = 255 * 255; Serial.println (z); עיכוב (200);}  
רמז: נסה "z = 255 * 255L;" או "z = 255 * (ארוך) 255;"
אני עשיתי. @MikaelPatel אכן עבדתי, האם תוכל להסביר את הסיבה העומדת מאחורי זה, והאם ישנם מקרים דומים לסוגים אחרים?
"באג" זה ישן כמו תכנות. כאשר אתה כותב מהדר "255" יוצר "קבוע שלם" עם ערך 255. כאשר מכפילים 255 ב 255 מכפילים שני "קבועים שלמים" ועל פי מוסכמות תוצאה של כפל כזה היא "מספר שלם". ואז אתה מטיל אותו במרומז לאורך זמן בעת ​​ביצוע מטלה. כאשר מכפילים "255" ב- "255L" למעשה מכפילים את "קבוע שלם" ב"קבוע ארוך "והתוצאה מכפל כזה היא" ארוכה ". תראה בעיה דומה כאשר אתה כותב 'float z = 1/5' התוצאה תהיה '0' מכיוון שתוצאות חלוקה שלמה עם מספר שלם שיועבר אחר כך לצוף.
Ref: https://gcc.gnu.org/wiki/avr-gcc הוא כל המידע שאתה צריך עבור מהדר AVR GCC. הכל קשור לטווח מספר 1) של "int" עבור יעד נתון, ו -2) הערכת מהדר של ביטויים קבועים.
@MikaelPatel עליך לענות על השאלות במקום לכתוב קטעי טופס מהם בסעיף ההערות.
שתיים תשובות:
Kwasmich
2019-02-05 15:51:25 UTC
view on stackexchange narkive permalink

לא, זה לא באג. אתה משתמש בביטוי קבוע זמן קומפילציה שהוא חתום int אלא אם כן נאמר אחרת. לכן אתה יכול לייצג רק מספרים בין -32768 ל- 32767. החישוב שלך 255 * 255 = 65025 חורג מהטווח. כך אתה רואה הצפה. בתקן C / C ++ הצפת הסוגים החתומים היא למעשה התנהגות לא מוגדרת. פירוש הדבר שמותר למהדר לעשות כל דבר מהצגת התשובה הנכונה לעצירה ולהתלקחות. רק לסוגים לא חתומים עם גודל ידוע כמו uint16_t יש התנהגות מוגבלת של הצפה. עליכם לקדם את החישוב הימני שלכם לסוג לא חתום ככה:

  z = 255U * 255U;  

בדרך זו אתה אומר למהדר את כוונתך ו אל תנחת ב"לא מוגדר-התנהגות-ארץ ".

@Juraj נכון, חשבתי שהוא חתום 16 סיביות בדיוק כמו 'int'. אך האחרון עדיין נכון. קבועי זמן הידור הם 'חתומים int', שהם 16 סיביות. אז הצד הימני של המטלה הוא הבעיה.
'לעטוף' לא נשמע נכון - אבל אני יודע מה אתה אומר
Michel Keijzers
2019-02-05 15:51:16 UTC
view on stackexchange narkive permalink

בהנחה שארוך הוא 4 בתים, זה אמור לעבוד.

עם זאת, אם איכשהו סוג ארוך הוא רק 2 בתים, או (סביר יותר להניח) השתמשת בסוג אחר או שיש הגדרה / טיפדף שגויה וזה זמן חתום (ברירת מחדל אם לא השתמשת במילת המפתח שלא חתומה), טווח הערכים הוא -32,768 עד 32,767 ו- 255 * 255 = 65,025 שאינו מחוץ לטווח.

אז אתה יכול תחילה לנסות להשתמש ב לא חתום ארוך .

ארוך הוא -2,147,483,648 עד 2,147,483,647
עם זמן לא חתום התוצאה הופכת ל: 4294966785.
התשובה של קוואסמיץ 'נכונה
@Juraj - אחד קצר שם: עמ '
@Juraj אני ואני כל כך ארוך מוגדר איכשהו כשני בתים.
זה לא. קוואסמיץ 'מסביר


שאלה ותשובה זו תורגמה אוטומטית מהשפה האנגלית.התוכן המקורי זמין ב- stackexchange, ואנו מודים לו על רישיון cc by-sa 4.0 עליו הוא מופץ.
Loading...