שאלה בC++. - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

שאלה בC++.


Amit Shani

Recommended Posts

אז בניתי מחלקה בשם Rational שמכילה nom ו denom - כלומר, המייצגת שבר.

אני צריך שהפעולה הבאה תפעל:

;r2=0.3 * r1

עכשיו, כתבתי אופרטור * למחלקה הזו:

Rational& operator*(double num)

{

Rational r=toFragment(num);

r.nom*=nom;

r.denom*=denom;

return r;

}

והבעיה הראשונה שלי היא שהפונקציה תרוץ רק במקרה של r2=r1*0.3 ולא ההפך, איך אני מתקן את זה?

הבעיה השניה שלי: toFragment הופכת double לשבר, התוכנית התחרבשה וכשחיפשתי למה, ראיתי שכשאני מעביר 0.3 לפונקציה במחלקה - המספר המועבר הוא בעצם 0.2999999 בחיים שלי לא נתקלתי בדבר כזה, ולמה זה מחרבש לי את התוכנית? כי הקוד של toFragment הוא:

Rational& toFragment(double num)

{

int count=0;

while(!isNatural(num))

{

num=num*10;

++count;

}

Rational r(int(num),pow(10,count));

return r;

}

אז יש פה 2 בעיות שאני לא יודע בכלל מאיפה להתחיל לסדר אותן (אני רק התחלתי ללמוד C++)

תודה מראש לעוזרים!

קישור לתוכן
שתף באתרים אחרים

אם תשים את הקוד בתוך תגית CODE, הוא יהיה קריא יותר.

והבעיה הראשונה שלי היא שהפונקציה תרוץ רק במקרה של r2=r1*0.3 ולא ההפך, איך אני מתקן את זה?
כותב בנאי שמקבל double ומייצר Rational, ומממש אופרטור * עם Rational בלבד. הקומפיילר ינסה (ולרוב יצליח) להפוך את הdouble לRational כדי להפעיל את האופרטור, וזה יפעל על הארגונמט הראשון באותה מידה כמו על השני.

לחילופין, אפשר לממש * operator כfriend, ואז אתה יכול לממש כמה גרסאות שתרצה. למשל:

friend Rational operator * (const Rational& x, double y)
friend Rational operator * (double x, const Rational& y)

וכו'.

הבעיה השניה שלי: toFragment הופכת double לשבר, התוכנית התחרבשה וכשחיפשתי למה, ראיתי שכשאני מעביר 0.3 לפונקציה במחלקה - המספר המועבר הוא בעצם 0.2999999 בחיים שלי לא נתקלתי בדבר כזה

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

קישור לתוכן
שתף באתרים אחרים

אם תשים את הקוד בתוך תגית CODE, הוא יהיה קריא יותר.

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

לחילופין, אפשר לממש * operator כfriend, ואז אתה יכול לממש כמה גרסאות שתרצה. למשל:

friend Rational operator * (const Rational& x, double y)
friend Rational operator * (double x, const Rational& y)

וכו'.

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

תודה רבה!

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


{
int count=0;
double nom=1,denom=2;
while(num>1){
--num;
++count;
}
double inf=0.0001;
while(abs(num-nom/denom)>inf)
if(nom/denom>num)
++denom;
else
++nom;
int nom1=int(nom),denom1=int(denom);
Rational r(nom1+denom1*count,denom1);
return r;
}
Rational& toFragment(double num)

קישור לתוכן
שתף באתרים אחרים

  • 2 שבועות מאוחר יותר...

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

אל תכתוב אופרטור הכפלה בין double ובין רציונלי.

אם אתה יוצר רציונלי מ-double ב CTOR דאג שהוא יהיה explicit כדי למנוע תאונות לא מכוונות

קישור לתוכן
שתף באתרים אחרים

ארכיון

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

×
  • צור חדש...