שאלה ב-c..

a9981

New member
שאלה ב-c..

שלום. אולי מישהו יכול להסביר לי איך אפשר לקבל מספר אקראי בין 1 ל-1000 ב-c? הכוונה היא , איך מגבילים את הבחירה עד ל-1000?? (אני מקבל מספרים בתחום ה-20000...) תודה.
 

זויברג

New member
בעזרת %

הסימן % בC מסמן פעולה אריתמטית של שארית, למשל 4 זה השארית של 20 כשהוא מתחלק ב8. די ברור שלא ניתן לקבל בפעולת השארית מספר יותר גדול מהמספר שמחלקים בו בשארית. לכן, סימן ה-% יגביל את המספרים האקראים שלך לגבול מסויים:
iRandNum = rand() % 1000; //up limit of random nums is 999​
מקווה שעזרתי
 

DNile

New member
לא, לא עזרת... ../images/Emo3.gif

זה אולי מגביל את המספרים, אבל יותר משזה מגביל את המספרים, זה מגביל את האקראיות.. תאר לך מצב כזה: יש לך פונקציה שמגרילה מספרים מ0 עד 4(כולל), ואתה רוצה להגביל אותם למספרים מ0 עד 2. לפי ההגיון שלך, נגריל מספר, ונעשה מודולו 3. רק מה? ההסתברות שיצא המספר 0 = 1/5. ההסתברות שיצא המספר 1 = 1/5, ההסתברות שיצא המספר 2 = 1/5, המספר 3 = 1/5, המספר 4 = 1/5. עכשיו אחרי פעולת המודולו: ההסתברות שיצא המספר 0 = 2/5 (גם 0 וגם 3 מתאימים), ההסתברות שיצא המספר 1 = 2/5 (גם 1 וגם 4 מתאימים), וההסתברות שיצא המספר 2 = 1/5 (רק 2 מתאים). מסקנה? ההתפלגות לא אחידה, עד כדי כך שלחלק מהמספרים יש הסתברות גדולה פי 2 מאשר מספרים אחרים. ולא, זה לא תקף רק לדוגמה של מספרים קטנים, גם אם פונקציית rand שנותנת מספרים מ0 עד 32767, אם תנסה להגריל בשיטה הזאת מספר מ0 עד 21845, תתקל בבעיה זהה. אז איך בכל זאת עושים? אם רוצים לעבור מטווח של 0 עד X לטווח של 0 עד Y: מכפילים את המספר שיצא לך בY, ומחלקים בX(וכמובן שדואגים שהטיפוס משתנה שלך מספיק גדול כדי להכיל את המספר X כפול Y, אחרת יהיו לך גלישות, והתוצאות לא יצא טובות).
 

דונטאלו

New member
אופס,חשבתי שאתה מקבל ערכים בתחום

ה-2000 ואז מה שכתבתי יכול לפעול, אפשר לעשות גם while(iRunNum>1000) { iRunNum=rand(); }
 

DNile

New member
לא, אי אפשר,

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

Zack DA

New member
רואים שאתה לומד באו"פ

"אני משאיר זאת כתרגיל לקורא לחשב מה ההסתברות"
 

דונטאלו

New member
למה?

ההסתברות להוציא מספר קטן מאלף מתוך 20 אלף הוא 1\20 שזה 5% וזה לא כל כך סיכוי קטן מה שעוד אפשר לעשות זה לולאה שתחסר 1000 מהמספר כל עוד המספר גדול מ-1000
 

DNile

New member
ועדיין ההסתברות קיימת

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

DNile

New member
Read the "Fine" shirshoor

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

DadleFish

New member
אפשר לעשות את זה,

אבל במקרה הספציפי הזה הסבירות לשגיאה גדולה מאוד (1 פחות 1 חלקי 2 בחזקת 22 בערך), ובכל מקרה אפשר למצוא מספר אקראי בין 0 ל-1000 בפעולת חשבון אחת פשוטה, אז למה להתאמץ?
 
למעלה