unzulässige verwendung einer fließkommazahl



  • Hallo,

    ich muss für meine Studienarbeit ein kleines Programm schreiben, dass Zufallszahlen Verteilungsbasiert erstellt.
    Ich habe bereits eine Oberfläche und kann auch gleichverteilte Zufallszahlen erzeugen.

    Dies ist mein erstes C++ - Programm, habe es nie gelernt und bin einfach durch Ausprobieren soweit gekommen wie ich jetzt bin.

    Nun will ich mit Hilfe der Polarmethode aus gleichverteilten Zahlen normalverteilte Zahlen machen und bekomme immer folgenden Fehler:

    Unzulässige Verwendung einer Fließkommazahl (zeile 110)

    Meine main.cpp:(Habe Zeile 110 dahintergeschrieben, befindet sich bei Button 1)

    //---------------------------------------------------------------------------
    #include <vcl.h>
    #pragma hdrstop
    #include <ctime>
    #include "Main.h"
    #include "About.h"
    #include <math.h>
    //---------------------------------------------------------------------------
    #pragma resource "*.dfm"
    TMainForm *MainForm;
    //---------------------------------------------------------------------------
    int verteilung=0;
    int a=0;
    int f=0;
    __fastcall TMainForm::TMainForm(TComponent *Owner)
    	: TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::CreateMDIChild(String Name)
    {
    	TMDIChild *Child;
    
    	//--- neues Fenster für untergeordnetes MDI erstellen ----
    	Child = new TMDIChild(Application);
    	Child->Caption = Name;
    	if (FileExists (Name))
    		Child->Memo1->Lines->LoadFromFile(Name);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::FileNew1Execute(TObject *Sender)
    {
    	CreateMDIChild("NONAME" + IntToStr(MDIChildCount + 1));
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::FileOpen1Execute(TObject *Sender)
    {
    	if (OpenDialog->Execute())
    		CreateMDIChild(OpenDialog->FileName);
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::HelpAbout1Execute(TObject *Sender)
    {
    	AboutBox->ShowModal();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::FileExit1Execute(TObject *Sender)
    {
    	Close();
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::RadioButton1Click(TObject *Sender)
    {
    verteilung=1;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::RadioButton2Click(TObject *Sender)
    {
    verteilung=2;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::RadioButton3Click(TObject *Sender)
    {
    verteilung=3;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::Button1Click(TObject *Sender)
    {
      int	b = StrToInt(Edit2->Text);
      int   c = StrToInt(Edit3->Text);
      int	d = StrToInt(Edit4->Text);
      double   x;
      double   y;
      double   q;
    
    	if (f==1) {
    				Memo1->Lines->Clear(); f=0;
    	}
    	if (verteilung==0) {
    	  Memo1->Lines->Add("Art der Verteilung wählen"); f=1;
    	}
    	else if (verteilung == 1) {
    
    	srand(static_cast<int>(time(NULL)));
    	for (unsigned u = 0; u < b; u++)
       {
    	  a= c + rand() % (d-c+1);   Memo1->Lines->Add(a);
       }
       }
    
       else if (verteilung==2)
    	{ 	srand(static_cast<int>(time(NULL)));
      //	for (unsigned u = 0; u < b; u++)
       //{
       do
    	  {
    	  x= rand()%2;
    	  y= rand()%2;
    	  q=(2*x-1)^2+(2*y-1)^2;     // Hier ist Zeile 110
    	  }
    	  while ((0<q)&&(q<1));
    	  a=(2*x-1)*sqrt(-2*log(q)/q);
    	  Memo1->Lines->Add(a);
    
       //	a= c + rand() % (d-c+1);   Memo1->Lines->Add(a);
    
       //}
       }
       else if (verteilung==3) { 	srand(static_cast<int>(time(NULL)));
    	for (unsigned u = 0; u < b; u++)
       {
    	  a= c + rand() % (d-c+1);   Memo1->Lines->Add(a);
       }
    
       }
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::Button2Click(TObject *Sender)
    {
      Memo1->Lines->Clear();
    
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TMainForm::Button3Click(TObject *Sender)
    {
    AnsiString SaveP = ExtractFilePath(Application->ExeName) + "Memo.txt";
    		Memo1->Lines->SaveToFile(SaveP) ;
    
    }
    //---------------------------------------------------------------------------
    

    Ich hoffe Jemand kann mir da weiter helfen.

    Gruß bcpschakal
    /edit akari : Bitte beim nächsten Posten von Quellcode die Code-Tags benutzen, sfds



  • rand() erzeugt eine integer-Zahl. Ist das in dem Algorithmus überhaupt so gewollt?



  • hm, eigentlich sollen als erstes bei der polarmethode 2 zahlen zwischen 0 und 1 erzeugt werden, hier x und y.

    jetzt wo du es sagst, ich will die als double und mache dann rand, (was nach deiner aussage ne int erzeugt), aber normal sollte das mit %2 doch wiederum ne zahl zwischen 0 und 1 ergeben oder?

    wie gesagt, hab von den genauen mechanismen nicht viel ahnung



  • OMG operator^ potenziert nicht, das ist bitweises EOR, verwende die Funktion pow().



  • bcpschakal schrieb:

    das mit %2 doch wiederum ne zahl zwischen 0 und 1 ergeben oder?

    Das ist der Rest eine Ganzahldivision. Mögliche Lösungen in den Zeilen 108f sind 0 und 1.



  • ok danke für die tipps, ^ war wirklich doof (wie gesagt, hab nie programmieren gelernt)
    und das mit dem zwischen 0 und 1 konnte natürlich nicht klappen

    so hier sollte es doch eigentlich funktionieren oder?

    x= rand()%10000;
    	  y= rand()%10000;
    	  x=x/10000;
    	  y=y/10000;
    

    jedoch bekomme ich dann ständig gleiche zahlen, zb:

    0,0629
    0,1613
    0,0629
    0,1613
    0,2663
    0,0146
    0,2663
    0,0146
    0,8997
    0,0787
    0,8997
    0,0787
    0,7919
    0,9511
    0,7919
    0,9511

    woran liegt das?

    des weiteren bekomme ich im verlauf des programms noch einen fehler:
    sqrt: DOMAIN error

    die wurzel nutze ich hier:

    a=(2*x-1)*sqrt((-2*log(q)/q));
    

    was hab ich dort falsch gemacht?



  • Weil du die Quadratwurzel aus einer negativen Zahl ziehst. Du solltest die Mathegrundlagen aber beherrschen wenn du Statistikprogramme scheibst.



  • bcpschakal schrieb:

    jedoch bekomme ich dann ständig gleiche zahlen

    Rufe srand() nur einmal auf, vllt im Konstruktor des Forms.



  • witte schrieb:

    Weil du die Quadratwurzel aus einer negativen Zahl ziehst. Du solltest die Mathegrundlagen aber beherrschen wenn du Statistikprogramme scheibst.

    tue ich nicht, da ln(q) neagtiv ist und ich somit eigtl die wurzel aus einer positiven zahl ziehen müsste

    (ich gehe davon aus, das log() dem ln entspricht)

    man sollte schon die mathematischen grundlagen kennen ....



  • bcpschakal schrieb:

    witte schrieb:

    Weil du die Quadratwurzel aus einer negativen Zahl ziehst. Du solltest die Mathegrundlagen aber beherrschen wenn du Statistikprogramme scheibst.

    tue ich nicht, da ln(q) neagtiv ist und ich somit eigtl die wurzel aus einer positiven zahl ziehen müsste

    (ich gehe davon aus, das log() dem ln entspricht)

    man sollte schon die mathematischen grundlagen kennen ....

    nicht beachten, hab grad gesehen, dass der algortihmus total banane ist

    mein mathe is richtig, aber das programm nicht 😉



  • Ich wollte gerade sagen dass die Abbruchbedingung der Schleife dann falsch ist...



  • so sollte es doch nun gehen oder?

    {
    	  x= rand()%10000;
    	  y= rand()%10000;
    	  x=x/10000;
    	  y=y/10000;
    		  q=(2*x-1)*(2*x-1) + (2*y-1)*(2*y-1);
    	  }
    	  while ((0>=q)||(q>=1));
    	  a=(2*x-1)*sqrt((-2*log(q)/q));
    

    nun ist log(q) auch wirklich negativ
    meine do while schleife war falsch



  • witte schrieb:

    Ich wollte gerade sagen dass die Abbruchbedingung der Schleife dann falsch ist...

    genau



  • hab noch eine weitere frage,

    ich speichere ja das memofeld in eine textdatei, wie kann ich nun den namen dieser datei noch wählbar machen?



  • Schau mal unter TSaveDialog, oder primitiver: eine InputBox, in die man den Dateinamen eingibt.


Anmelden zum Antworten