Rechteckverteilung bei Zufallszahlen



  • 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.


  • Mod

    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. 😃


Anmelden zum Antworten