עבור לתוכן

חידה למתכנתים בשפת C

Featured Replies

פורסם

הקוד הבא:


#include <stdio.h>
#include <math.h>

int main(void)
{
double a;
a = log(1000)/log(10);
// we all know that log 1000 / log 10 is 3
printf("if a is %.0lf\n", a);
if ((int)a == 3)
printf("then why isn't this line being print?\n");
}

תריצו אותו, ותקבלו:


mycomp ice # gcc -o riddle riddle.c -lmath
mycomp ice # ./riddle
if a is 3

שורת ה PRINTF השניה לא תתבצע, מדוע?

ולא פחות חשוב, מה מוסר ההשכל מכך?

---------------

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

פורסם

האממ זה כן מדפיס את השורה השנייה...

לפחות אצלי הוא כן.

פורסם

אבל זה כן מדפיס...

VC++6

פורסם
  • מחבר

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

פורסם

משהו עם ה CASTING ?

פורסם

ניסית לעשות casting למשתנה זמני אחר, ולא לזה שנוצר לך אוטומטית?

פורסם
  • מחבר

ניסית לעשות casting למשתנה זמני אחר, ולא לזה שנוצר לך אוטומטית?

#include <stdio.h>

#include <math.h>

int main(void)

{

double a;

int b;

a = log(1000)/log(10);

// we all know that log 1000 / log 10 is 3

printf("if a is %.0lf\n", a);

b = (int)a;

if (b == 3)

printf("then why isn't this line being print?\n");

}

גם לא עובד, אותו דבר כמו מקודם... הייתי מעדיף שתעלו על הבעיה לבד, במקום לשאול מה לא נכון :) זה לא בעיה כזו טריוויאלית, ואם יש לכם LINUX או CYGWIN או קומפילר אחר חוץ מ MICROSOFT, תנסו לתקן את זה שם...

פורסם

יש איזה קומפיילר חינמי שאפשר לבדוק עליו?

כי זה באמת מעניין למה הבעיה... אני רוצה לראות איפה היא.

פורסם
  • מחבר

ה WINDOWS שלי נהרס לפני כמה שעות, אז קשה לי לדעת מה יריץ את זה טוב ומה לא.. אפשר לנסות את TURBO C, ו/או CYGWIN....

פורסם

מה עושה הדגל lmath- ?

פורסם
  • מחבר

זה אומר לקומפילר להוסיף את הספריה המתמטית לתוכנית (בשביל הפקודה LOG) בלי זה, התוכנית לא תתקמפל.....

פורסם

טוב זאת חידה קלה (לפחות יותר מהקודמת, שהיתה ממש נחמדה אגב, ולא הצלחתי אותה).

התוצאות המתמטיות של LOG לא מדויקות ולכן המספר המתקבל הוא לא בדיוק בדיוק 3, אלא טיפונת פחות.

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

לעומת זאת המרה ל-INT מבצעת עיגול כלפי מטה (FLOOR) ל-2.

הפתרון הוא להחליף את

(int)a

ב-

(int)round(a)

פורסם

יפה :xyxthumbs:

אבל למה התוצאות של לוג לא מדוייקות? אם המחשבון יכול למה המחשב לא יכול? (אורך אוגרים קטן יותר?)

פורסם

זה דיי תלוי בפיתוח שעשו שם לlog...

פורסם
  • מחבר

טוב זאת חידה קלה (לפחות יותר מהקודמת, שהיתה ממש נחמדה אגב, ולא הצלחתי אותה).

התוצאות המתמטיות של LOG לא מדויקות ולכן המספר המתקבל הוא לא בדיוק בדיוק 3, אלא טיפונת פחות.

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

לעומת זאת המרה ל-INT מבצעת עיגול כלפי מטה (FLOOR) ל-2.

הפתרון הוא להחליף את

(int)a

ב-

(int)round(a)

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

בכל מקרה, המוסר השכל, זה להשתמש ב ROUND ולא ב INT סתם ככה (כאשר רוצים לעשות המרה מ DOUBLE ל INT), הוא לא מבצע המרה כלפי מטה, פשוט הוא חותך את המשתנה ה DOUBLE בנקודה כלשהי (וה DOUBLE הוא ל 3.00000 הוא 2.99999999999 וה PRINTF יש קוד בפנים שעושה עיגול למספר ל 3)...

ארכיון

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

דיונים חדשים