Rechteckverteilung bei Zufallszahlen
-
Mein Testprogramm:
#include <stdio.h> int r[201]; int main() { int x; srand(time(NULL)); int i; for (i = 0; i < 1000 * 1000; i++) { x = rand() % 101; x = (rand() % 2 == 0) ? x : -x; r[x + 100]++; } for (i = 0; i < 201; i++) printf("%d:\t%d\n", i - 100, r[i]); return 0; }
Ergebnis:
-100: 4871 -99: 4944 -98: 4833 -97: 4909 -96: 4999 -95: 4870 -94: 4989 -93: 4853 -92: 4881 -91: 4808 -90: 4979 -89: 5037 -88: 4901 -87: 5045 -86: 5112 -85: 4951 -84: 4820 -83: 4917 -82: 4910 -81: 4947 -80: 4979 -79: 4890 -78: 4993 -77: 4966 -76: 4878 -75: 4925 -74: 4995 -73: 4916 -72: 4940 -71: 5105 -70: 5060 -69: 4887 -68: 4881 -67: 4934 -66: 4916 -65: 4993 -64: 4891 -63: 4948 -62: 4983 -61: 5198 -60: 4793 -59: 4968 -58: 4930 -57: 4906 -56: 4887 -55: 4880 -54: 5023 -53: 5043 -52: 5041 -51: 4945 -50: 4957 -49: 5000 -48: 5022 -47: 5003 -46: 4925 -45: 4860 -44: 5029 -43: 4935 -42: 5051 -41: 4940 -40: 4992 -39: 5025 -38: 4786 -37: 4848 -36: 4894 -35: 5041 -34: 4927 -33: 5028 -32: 5057 -31: 5042 -30: 4916 -29: 5006 -28: 4903 -27: 4971 -26: 4965 -25: 4919 -24: 4966 -23: 4983 -22: 4924 -21: 4951 -20: 4902 -19: 4906 -18: 5029 -17: 5055 -16: 5007 -15: 4988 -14: 4944 -13: 4930 -12: 5036 -11: 4944 -10: 4958 -9: 4838 -8: 4859 -7: 5007 -6: 4944 -5: 5064 -4: 5024 -3: 4955 -2: 4878 -1: 4861 0: 9837 1: 4995 2: 4906 3: 4942 4: 5008 5: 4950 6: 4907 7: 4934 8: 4929 9: 4885 10: 4983 11: 4910 12: 4871 13: 5084 14: 4838 15: 4856 16: 4983 17: 5030 18: 4898 19: 4921 20: 4834 21: 4996 22: 4998 23: 4910 24: 5026 25: 5013 26: 5026 27: 4889 28: 4968 29: 4963 30: 5009 31: 4880 32: 4894 33: 5058 34: 5045 35: 4941 36: 5037 37: 4871 38: 5080 39: 4891 40: 4978 41: 4821 42: 4918 43: 5001 44: 5018 45: 4914 46: 4981 47: 4813 48: 4974 49: 5006 50: 5007 51: 4935 52: 4921 53: 4973 54: 4962 55: 4866 56: 4925 57: 4999 58: 5044 59: 4996 60: 4927 61: 4979 62: 5038 63: 4968 64: 4939 65: 4952 66: 4948 67: 4930 68: 4860 69: 4884 70: 5041 71: 4986 72: 5119 73: 4950 74: 4948 75: 4921 76: 4913 77: 4955 78: 5011 79: 4906 80: 5017 81: 5008 82: 4916 83: 4994 84: 5057 85: 4882 86: 4884 87: 4810 88: 5011 89: 4862 90: 4992 91: 4877 92: 4907 93: 4971 94: 4934 95: 4944 96: 4809 97: 4865 98: 4930 99: 4938 100: 4904
Sieht doch super aus. Nur die 0 ist doppelt.
-
earli schrieb:
Nur die 0 ist doppelt.
Dann mach statt
x = rand() % 101; x = (rand() % 2 == 0) ? x : -x;
x_k = (rand()%201)-100
und die doppelte 0 ist auch weg.
-
DirkB schrieb:
earli schrieb:
Nur die 0 ist doppelt.
Dann mach statt
x = rand() % 101; x = (rand() % 2 == 0) ? x : -x;
x_k = (rand()%201)-100
und die doppelte 0 ist auch weg.
Ich hab das ja genau vom Fragesteller übernommen.
-
Also die Null darf ruhig doppelt vorkommen. Macht ja nichts!
[cpp]
#include <stdio.h> #include <time.h> #include <stdlib.h> int main(void) { int zz; long anzahl = 10000000; int i = 0; int kleiner=0; int groesser=0; srand ( time(NULL) ); while(i <= anzahl) { zz = rand()%101; if(zz <= 50) { kleiner++; } else { groesser++; } i++; } printf("\n\nkleiner:%i\n\ngroesser:%i", kleiner, groesser); return 0; }
-
Du hast mit rand()%101; auch 101 Werte (0 bis 100)
Von 00 bis 050 hast du 51 Werte und
von 51 bis 100 hast du 50 Werte.Kalr dass das Ungleich verteilt ist.
-
Ist mir auch gerade aufgefallen. Also mach rand eine Rechteckverteilung..
Oh maaaan, mein Latein ist solangsam echt am Ende.
Ich verstehe nicht, warum meine erechnete Zahl pi nie so genau wird.
-
Hans-Stein schrieb:
Also ich kann leider nur einen Teil von meinem Programm einstellen. Die Aufgabe ist grafisch zu lösen, deswegen lasst euch von den unterprogrammen greendots(hwndMain) nicht stören:
BOOL punkte (HWND hwnd) { extern int x_k, y_k; //Koordinaten double z_k; //Fallunterscheidung double wurzel; //Quadratzwurzel int zaehler = 0; //Zaehlt die Anzahl extern int anzahl; //Eingelesene Versuchsanzahl extern int in; //Anzahl der Punkte im Kreis in = 0; extern int out; //Anzahl der Punkte außerhalb des Kreis out = 0; int x = 0; int y = 0; extern int aus; //Schalter für Animation extern HWND hwndMain; //Für Programmaufruf von reddots/greendots(hwndMain) extern int schalter; //Schalter für WM_Paint extern double gr; extern double gr2; printf("\n\nAusknopf: %i", aus); srand(time(NULL)); while(anzahl+1 >= zaehler) { zaehler++; //X-Koord. würfeln x_k = rand()%101; x_k = ((rand()%2)==0)?x_k:-x_k; my_random_double(); //Y-Koord. würfeln y_k = rand()%101; y_k = ((rand()%2)==0)?y_k:-y_k; //printf("\n\n %i\n %i", x_k, y_k); wurzel = sqrt((double)x_k*(double)x_k + (double)y_k*(double)y_k); if(wurzel == 100) { z_k = rand()%2; wurzel = wurzel - z_k; printf("\n\nWurzel: %lf", wurzel); } //Fallunterscheidung if (wurzel < 100) { in++; if(aus != 1) { greendots(hwndMain); } } else { out++; if(aus != 1) { reddots(hwndMain); } } } schalter = 0; berechnung(hwnd); return 0; }
Was ist my_random_double();?
-
So jetzt sieht man hier, dass mehr Werte kleiner 0.5 sind als größer:
#include <stdio.h> #include <math.h> #include <stdlib.h> int main (void) { double z1; // Zufallszahl double z2; double wert = 0; int v1, v2; // Vorzeichen double innerhalb = 0; double radius; double anzahl=4000; // Anzahl der Versuche double i; double pi; while (anzahl != 0) { innerhalb = 0; printf("\nBitte die Anzahl der Versuche eingeben - 0 = Ende -: "); scanf("%lf", &anzahl); for (i = 1.; i <= anzahl; i++) { z1 = rand() % 10001 / 10000.; z2 = rand() % 10001 / 10000.; if (z1 < 0.5) wert++; v1 = rand() % 2; v2 = rand() % 2; if (v1 == 0) z1 = -z1; if (v2 == 0) z2 = -z2; radius = sqrt((double)z1* (double)z1 + (double)z2 *(double)z2 ); if (radius < 1.) innerhalb++; } pi = 4 * (innerhalb) / anzahl; printf("\nBei %20.0lf ist Wert %lf PI : %20.10lf",(double) anzahl, wert, pi); } return 0; }
-
Da hast du doch das gleiche Problem wie mit deinen 101.
Bsp:
Angenommen RAND_MAX sei 65535. Dann ergibt RAND_MAX % 10001 / 10000 = 0.5529
Du hast dann 6 mal den vollen Bereich und dann noch gut die Hälfte. Klar das da mehr Werte kleiner 0.5 auftauchen.Schreib mal statt
z1 = rand() % 10001 / 10000.; if (z1 < 0.5) wert++; v1 = rand() % 2; if (v1 == 0) z1 = -z1;
besser
z1 = (rand() * 2.0 / (double)RAND_MAX) -1.0; if (z1 < 0) wert++;
Und benutze bitte srand().
-
Ja, aber der Bereich von 0-0.4999 ist kleiner als der Bereich von 0.5-1.0
0, 1, 2 ,3 ,4 ||,5 ,6 ,7 ,8 ,9 1,0
das heißt der Bereich in dem die Zahl größer sein müsste ist sogar 6 Teile. Und trotzdem sind im kleineren Bereich mehr Zufallszahlen.
-
Oder nochmal anderst dargestellt:
Wertebereich: [0;5[ < [5;10]
x > Versuche-x
-
1. Das sind 5000 gegenüber 5001 Werten. (und nicht 5 gegen 6)
2. Hast du ohne srand(time(NULL)); bei jedem Programmstart immer die selben Zufallswerte.
-
Wieso weigerst du dich so beharrlich die dir schon gezeigten Fehler in deinem Programm zu verbessern und argumentierst stattdessen, dass der Computer falsch rechnet? Meinst du wirklich du hättest doch Recht und alle anderen hätten einen solch offensichtlichen Rechenfehler noch nie bemerkt?
-
#include <stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> int main (void) { double z1; // Zufallszahl double z2; double wert = 0; int v1, v2; // Vorzeichen double innerhalb = 0; double radius; double anzahl=4000; // Anzahl der Versuche double i; double pi; while (anzahl != 0) { innerhalb = 0; printf("\nBitte die Anzahl der Versuche eingeben - 0 = Ende -: "); scanf("%lf", &anzahl); srand(time(NULL)); for (i = 1.; i <= anzahl; i++) { z1 = rand() % 101; z2 = rand() % 101; if (z1 < 50) wert++; v1 = rand() % 2; v2 = rand() % 2; if (v1 == 0) z1 = -z1; if (v2 == 0) z2 = -z2; radius = sqrt((double)z1* (double)z1 + (double)z2 *(double)z2 ); if (radius < 100) innerhalb++; } pi = 4 * (innerhalb) / anzahl; printf("\nBei %20.0lf ist Wert %lf PI : %20.10lf",(double) anzahl, wert, pi); } return 0; }
hier mit srand und mit zahlen von 0 bis 100
und die Anzahl der Werte <50 ist trotzdem größer.
-
Du machst die Sache mit der ganzen Hin- und Herrechnerei nicht besser.
Zudem prüfst du bei dir auch nur jeden 4. Zufallswert ob der < 0.5 ist.Da kannst du bei einer Ampel auch nur auf das obere Licht schauen und dich wundern, dass du immer Rot (und Schwarz) siehst.
#include <stdio.h> #include <math.h> #include <stdlib.h> #include <time.h> int main (void) { double z1; // Zufallszahl double z2; long wert = 0; long innerhalb = 0; double radius; long anzahl=RAND_MAX/100; // Anzahl der Versuche long i; int durchl = 10; double pi; srand(time(NULL)); for(;durchl>0;durchl--) { innerhalb = 0; wert = 0; printf("\nBitte die Anzahl der Versuche eingeben - 0 = Ende -: "); // scanf("%ld", &anzahl); for (i = 1; i < anzahl; i++) { z1 = (rand() / (double)RAND_MAX); // Wird eh quadriert z2 = (rand() / (double)RAND_MAX); // deswegen keine negativen Zahlen nötig if (z1 < 0.5) wert++; else wert--; if (z2 < 0.5) wert++; else wert--; radius = z1* z1 + z2 *z2; // Wenn die Wurzel < 1 ist, ist auch das Quadrat < 1 if (radius < 1.) innerhalb++; } pi = 4.0 * innerhalb / anzahl; printf("\nBei %ld ist Wert %ld PI : %.10f %e", anzahl, wert, pi, pi-3.141592654); } return 0; }
Bei mir kommen für wert positive und negative Werte raus.
-
So jetzt hats auch der Maschinenbauer verstanden
Ich danke für die Geduld!!
-
Ach so, Maschinenbauer.
Sag das doch gleich.
Dann hätten wir doch noch ein paar Tropfen Öl dazu gegeben, damit es flutscht.