Aufgabenstellung(Strukturen, Zeiger, auslesen/einlesen...)


  • Mod

    guest123 schrieb:

    Ja hier kann man meines Erachtens die Multiplikations-Funktion, die ich oben postete nutzen denn:
    Wenn im Nenner ein j (bzw. i) ist muss man konjugiert komplex erweitern... das heißt das man dann das Vorzeichen vom j ändert und dann mit dem Zähler multipliziert.
    Hier kann ich gar nicht die Funktion dazu verwenden, denn das Ergebnis der Multiplikation ist anders wie das Ergebnis des Zählers der Division, weil man ja beim komplex konjugiert erweitern das Vorzeichen das j ändert und dann erst Multipliziert.

    Häh? Irgendwie fehlen dir irgendwie ein paar Wörter in dem Beitrag, ich verstehe nicht, was du meinst. Und selbst wenn ich meine magische Kristallkugel benutzt, was du wohl meinen könntest, so kann ich deine Schwierigkeiten nicht nachvollziehen. Schon einmal da dran gedacht, dass man auch Werte kopieren kann?

    Na, die Namen sprechen doch wohl sehr gut: write soll wohl etwas schreiben. Die Methode soll eine Variable namens filename, also Dateiname entgegen nehmen. Außerdem noch ein Array von deinen Structs und eine Längenangabe. Nun rate mal, was wohl wohin geschrieben werden soll.

    Ja also die Ergebnisse wie sich sagte in ein neues Textfile rein? Oder was nun?
    Sorry, aber ich komm nicht damit klar wenn nciht genau in der Angabe steht was ich machen soll... 😞

    Na, du sollst die Funktion write schreiben. Von aufrufen steht da nix.



  • Zum Dividieren:

    Siehe hier bitte: http://imageshack.us/photo/my-images/80/complexf.png/
    Ich hoffe es ist hier verständlicher.

    Zum c_write_file:

    Ja, stimmt da steht nur schreiben Sie die Funktion, aber nix von aufrufen. Soll man das so Wort wörtlich nehmen? Was hat es für einen Sinn nicht die Funktion aufrufen und einfach schreiben? Was soll ich nun tun?

    mfg guest


  • Mod

    guest123 schrieb:

    Zum Dividieren:

    Siehe hier bitte: http://imageshack.us/photo/my-images/80/complexf.png/
    Ich hoffe es ist hier verständlicher.

    Sag mal, liest du überhaupt, was ich schreibe? Du musst mit dem komplex kunjugierten multiplizieren!

    Zum c_write_file:

    Ja, stimmt da steht nur schreiben Sie die Funktion, aber nix von aufrufen. Soll man das so Wort wörtlich nehmen? Was hat es für einen Sinn nicht die Funktion aufrufen und einfach schreiben? Was soll ich nun tun?

    🙄
    Aufgeben.



  • Ja natürlich lese ich was du schreibst.

    Nur kann ich leider nirgends herauslesen wo du erklärst wie man die Funktion "c_multi" zur Kommplexendivision verwenden kann.

    Zeig mir es bitte.

    Und Aufgeben tue ich nicht :D.


  • Mod

    SeppJ schrieb:

    Nochmal in Worten: Du multiplizierst a mit dem komplex konjugierten von b. Dann rechnest du noch Das Betragsquadrat von b aus, meinetwegen indem du b mit dem komplex konjugierten von b multiplizierst. Da das Betragsquadrat eine reelle Zahl ist, zerfällt die noch verbleibende Division von ab* durch das Betragsquadrat zu einer Division einer komplexen Zahl, durch eine reelle Zahl. Das heißt, du teilst jeweils den Real und den Imaginärteil von ab* durch |b|².



  • Danke!

    Also soll ich c_multi an der Stelle einsetzen oder aufrufen?, wo bei der Division Multipliziert wird(in dem fall konjugiert komplex erweitert)?


  • Mod

    Erklär mal, was du mit Einsetzen und Aufrufen meinst und wo der Unterschied ist.



  • Alda, ihr solltet nie mit Menschen zusammen arbeiten, das ist ja grauenhaft zu lesen. Fachidiot erklärt viel zu kompliziert und Fachneuling redet drum rum.


  • Mod

    uijuijui schrieb:

    Alda, ihr solltet nie mit Menschen zusammen arbeiten, das ist ja grauenhaft zu lesen. Fachidiot erklärt viel zu kompliziert und Fachneuling redet drum rum.

    Das heißt bloß, dass ich besser nur mit anderen Fachidioten reden sollte. Oh Wunder, das ist das, was ich die meiste Zeit tue. Daher wohl auch das Kommunikationsproblem. Und guest123 sollte sich wohl in der Tat jemanden suchen, der besser auf ihn eingehen kann. Wir haben jetzt schon 6x die gleiche Frage und 5x die gleiche Antwort gehabt, ohne jedweden Fortschritt. Ich glaube, ich klinke mich besser aus, bevor es 6:6 steht.



  • Sorry für die Umstände das es eben solange dauert bei mir bis ich das verstanden hab.

    Hier einige Programm-Auschnitte(c_divi habe ich selbst geschrieben Rest war vorgegeben, da ich nur bei der Übung Ergänzen musste):

    Hauptprogramm

    complex result3={1.0,0.0};//real muss 1 sein, da da result3 am Anfang gleich den 1. Wert  von arrayValues sein muss.
    
    while(n<file_len)
    	{
    	  result3=c_divi(result3,*(arrayValues+n),n);
    	  n++;
    	}
    	printf("\nQuotient aller Komplexer Zahlen:\n");
    	c_print(result3);
    

    Unterprogramm zum Ausgeben:

    void c_print(complex a)
    {
      printf("%lf + j%lf",a.real,a.imag);
    }
    

    Unterprogramm zum Dividieren(müsste eigentlich so stimmt oder?):

    complex c_divi(complex a, complex b, int n)
    {
      complex result3;
      complex result2;
      double nenner=1.0;
    
      if(n >= 1)
      {
        nenner = (b.real*b.real) + (b.imag*b.imag);
    	b.imag=-b.imag;
      }
    
      result2 = c_multi(a,b);
    
      result3.real=result2.real/nenner;
      result3.imag=result2.imag/nenner;
    
      return result3;
    }
    

    Das Problem ist, dass es mir nichts ausgibt... Ich bin das Programm mit Einzelschritt F11 durchgegangen, aber es kommt 0+0j raus obwohl ganz eindeutig am Schluss result3={5.xxxxxxxx/4.xxxxxxxxxx} oder so rauskommt.

    Und die Ausgabe müsste doch auch stimmen, da es ja das Addieren, Subtrahieren und Multiplizieren richtig ausgibt?

    Was könnte es da haben?Die if ist dazu da, dass der 1. Wert von result3 dem 1. Wert von arrayValues übereinstimmt und halt dann richtig zu übergeben.

    LG guest123



  • guest123 schrieb:

    Das Problem ist, dass es mir nichts ausgibt... Ich bin das Programm mit Einzelschritt F11 durchgegangen, aber es kommt 0+0j raus obwohl ganz eindeutig am Schluss result3={5.xxxxxxxx/4.xxxxxxxxxx} oder so rauskommt.

    Was heißt "nichts ausgibt"? Gibt "es" nichts aus oder gibt es 0+0j aus?
    Deine Probleme mit Deutsch scheinen gravierender zu sein, als die mit C.
    Wenn "es" nichts ausgibt, solltest du noch ein fflush(stdout) folgen lassen.
    Der printf-Formatspezifizierer für double ist %f und nicht %lf.


  • Mod

    guest123 schrieb:

    Unterprogramm zum Dividieren(müsste eigentlich so stimmt oder?):

    Was soll das n? (Ja, ich kann mir das erschließen, was das soll, aber das ist sehr ungeschickt gemacht, daher frage ich nach, damit du über dieses Design nachdenkst. Wieso soll eine Division von dem n wissen müssen?)

    Das Problem ist, dass es mir nichts ausgibt... Ich bin das Programm mit Einzelschritt F11 durchgegangen, aber es kommt 0+0j raus obwohl ganz eindeutig am Schluss result3={5.xxxxxxxx/4.xxxxxxxxxx} oder so rauskommt.

    Sicher? Wenn man mit der Zahl 1 anfängt und diese immer wieder teilt ist das nicht so ungewöhnlich, wenn irgendwann etwas nahe 0 heraus kommt.

    Falls wirklich nicht 0 herauskommt: Wenn du das Programm im Einzelschritt durchgehst, dann schau dir die Werte der Variablen an und guck, ab wann das Ergebnis falsch ist. Nur beim Draufgucken sehe ich im Moment keinen Fehler.



  • @Wutz: Sorry ich meinte natürlich 0+j0.

    @Seppj:
    In der Text-Datei steht:

    2,3
    64,4
    7,7
    2,4.5
    7.8,5.44
    .
    .
    .
    

    Wenn ich das if wegmache bei c_divi, dann würde es am Anfang gleich den Nenn berechnen und das Vorzeichem beim j umändern(bei 2+3j). Und somit dividiere man statt 2+3j/64+4j --> .../64+4j. Darum braucht man die if, dass es dann beim 2. c_divi Durchgang 2+3j/64+4j dividiert und dieses Ergebnis dann durch 7+7j usw.

    Ich hab gar nichts am Programm(außer das %lf zu %l) verändert und 'schwubsdiwubs' ist "Kein Quellcode an dieser Stelle verfügbar". Diese Meldung kommt beim 3. geposteten Code Zeile 9.

    Diese Meldung habe ich noch nie bekommen, was hat das jetzt genau zu bedeuten bzw. was hab ich für einen Fehler gemacht?

    PS:Das Programm besteht aus 2 Header-Files und 3 C-Files(Die Files waren vorgegeben, da ich nur Ergänzungen machen musste)

    Soll ich vielleicht das ganze Programm posten?



  • edit:%lf zu %f geändert...(vielleicht sollte ich mich registrieren im das zu verhindern)



  • Ok, dann hier das ganze Programm:

    #ifndef _compl_h_
    #define _compl_h_
    
    struct complex_struct
    {
      double real;
      double imag;
    };
    
    typedef struct complex_struct complex;
    
    complex c_add(complex a, complex b);
    
    complex c_sub(complex a, complex b);
    
    complex c_multi(complex a, complex); 
    
    complex c_divi(complex a, complex b, int n);
    
    complex c_kehr(complex a, complex b);
    
    void c_print(complex a);
    
    #endif
    

    1.C-file:

    #include "compl.h"
    #include <stdio.h>
    
    complex c_add(complex a, complex b)
    {
      complex result;
      result.real = a.real + b.real;
      result.imag = a.imag + b.imag;
      return result;
    }
    
    complex c_sub(complex a, complex b)
    {
      complex result1;
      result1.real = a.real - b.real;
      result1.imag = a.imag - b.imag;
      return result1;
    }
    
    complex c_multi(complex a, complex b)
    {
      complex result2;
      result2.real = (a.real*b.real) - (a.imag*b.imag);
      result2.imag = (a.imag*b.real) + (b.imag*a.real);
      return result2;
    }
    
    complex c_divi(complex a, complex b, int n)
    {
      complex result3;
      complex result2;
      double nenner=1.0;
    
      if(n >= 1)
      {
        nenner = (b.real*b.real) + (b.imag*b.imag);
    	b.imag=-b.imag;
      }
    
      result2 = c_multi(a,b);
    
      result3.real=result2.real/nenner;
      result3.imag=result2.imag/nenner;
    
      return result3;
    }
    
    complex c_kehr(complex a, complex b)
    {
      complex result4;
      double nenner=0.0;
    
      nenner = (b.real*b.real) + (b.imag*b.imag);
    
      result4.real=a.real+(b.real/nenner);
      result4.imag=a.imag+(-b.imag/nenner);
    
      return result4;
    }
    
    void c_print(complex a)
    {
      printf("%lf + j%lf",a.real,a.imag);
    }
    

    2.h-file:

    #include "compl.h"
    #ifndef _complfile_h_
    #define _complfile_h_ 1
    
    complex* c_read_file(char filename[], int* len);
    
    //void c_write_file(char filename[], complex compl_array[], int len);
    
    int c_file_len(char filename[]);
    
    #endif
    

    2.c-File

    #include <stdio.h>
    #include <stdlib.h>
    #include "compl.h"
    #include "complfile.h"
    
    complex* c_read_file(char filename[], int* len)
    {
      FILE *inFile=NULL;
      complex *arrayValues=NULL;
      complex *actVal = NULL;
      int n=0;
    
      inFile=fopen(filename,"r");
      if (inFile != NULL) 
      {
        arrayValues=(complex *)malloc(sizeof(complex)* *len);
        if (arrayValues != NULL)
        {
          actVal=arrayValues;
          for(n=0; n<*len; n++)
          {
    		fscanf(inFile,"%lf,%lf",&actVal->real,&actVal->imag);
    		actVal++;
          }
          fclose(inFile);
        }
        else
        {
          printf("Memory allocation failure for Data of File %s !\n",filename);
        }
      }
      else
      {
        printf("File %s could not be opened!\n",filename);
      }
    	return(arrayValues);
    }
    
    //void c_write_file(char filename1[], complex compl_array[], int len)
    //{
    //  FILE *inFile=NULL;
    //
    //  int x=0;
    //
    //  inFile=fopen(filename1,"w");
    //  if(inFile != NULL)
    //  {
    //    for(x=0; x<len; x++)
    //	{
    //	  fprintf()
    //	}
    //  }
    //  else
    //  {
    //    printf("File %s could not be opened!\n",filname1);
    //  }
    //}
    
    int c_file_len(char filename[])
    {
      int len =0;
      complex dummy;
      FILE *inFile=NULL;
    
      inFile=fopen(filename,"r");
      if (inFile != NULL) 
      {
    	while (!feof(inFile))
    	{
    	  if (fscanf(inFile,"%lf,%lf",&dummy.real,&dummy.imag) == 2)
    	  {
    	    len++;
    	  }
        }
        fclose(inFile);
      }
      else
      {
        printf("File %s could not be opened!\n",filename);
      	len = -1;
      }
      return (len);
    }
    

    3. C-file:

    #include <stdio.h>
    #include <stdlib.h>
    #include "compl.h"
    #include "complfile.h"
    
    #define MAX_STRLEN 20
    
    int main()
    {
      FILE *inFile=NULL;
      char filename[MAX_STRLEN]="daten_in.txt";
      char filename1[MAX_STRLEN]="ergebnis.txt";
      int file_len = 0;
    
      int n=0;
    
      complex *arrayValues=NULL;
      complex result = {0.0,0.0};
      complex result1 = {0.0,0.0};
      complex result2 = {1.0,0.0};
      complex result3 = {1.0,0.0};
      complex result4 = {0.0,0.0};
    
      file_len = c_file_len(filename);
      arrayValues = c_read_file(filename,&file_len);
    
      if (arrayValues != NULL)
      {
        while(n<file_len)
        {
    	  result=c_add(result,*(arrayValues+n));
          n++;
        }
        printf("\nSumme aller Komplexer Zahlen:\n");
        c_print(result);
        printf("\n");
    	n=0;
    
    	while(n<file_len)
        {
          result1=c_sub(result1,*(arrayValues+n));
          n++;
        }
        printf("\nDifferenz aller Komplexer Zahlen:\n");
        c_print(result1);
        printf("\n");
        n=0;  
    
        while(n<file_len)
    	{
    	  result2=c_multi(result2,*(arrayValues+n));
          n++;
        }
    	printf("\nProdukt aller Komplexer Zahlen:\n");
    	c_print(result2);
    	printf("\n");
        n=0;
    
    	while(n<file_len)
    	{
    	  result3=c_divi(result3,*(arrayValues+n),n);
    	  n++;
    	}
    	printf("\nQuotient aller Komplexer Zahlen:\n");
    	c_print(result3);
    	printf("\n");
            n=0;
    
    	while(n<file_len)
    	{
    	  result4=c_kehr(result4,*(arrayValues+n));
    	  n++;
    	}
    	printf("\nKehrwert aller Komplexer Zahlen:\n");
    	c_print(result4);
    	printf("\n");
    
    	//c_write_file(filename1,array1,len);
    
    	free(arrayValues);
      }
    
      return(0);
    }
    

    So..., ok das mit dem Kehrwert müsste noch nicht ganz fertig sein, aber egal jetzt, wichtig ist jetzt - Ich zitiere:

    Wenn ich das if wegmache bei c_divi, dann würde es am Anfang gleich den Nenn berechnen und das Vorzeichem beim j umändern(bei 2+3j). Und somit dividiere man statt 2+3j/64+4j --> .../64+4j. Darum braucht man die if, dass es dann beim 2. c_divi Durchgang 2+3j/64+4j dividiert und dieses Ergebnis dann durch 7+7j usw.

    Ok, das mit dieser Meldung ist jetzt auf einmal weg..., aber gestern wars noch da 😕 , aber ok gut...

    Ich bin jetzt nochmal mit Einzelschritt durchgegangen... und das letzte Ergebnis bei der Division also result3 ist.
    result3{real=5.2946270969590323e-016 imag=2.5432167846871301e-016 }
    Und genau diese Zahlen werden auch ins complex a übergeben, aber leider nicht ausgegeben, anstatt wird wie gesagt einfach 0+0j ausgegeben.

    Beim c_kehr gibt es was(wie bei c_add, c_sub und c_multi) aus, genau den Wert, der auch bei Einzelschritt rauskommt nämlich:
    result4{real=1.1400487862107511 imag=-1.1311106227783347}

    Kann mir bitte einer helfen?


  • Mod

    Schreib mal 5.2946270969590323e-016 in Dezimalschreibweise auf 7 Stellen genau hin und staune.

    Und dann schaust du selbstständig in eine Referenz von printf und versuchst das Problem zu lösen. Ich verrate dir mit Absicht nicht sofort die Lösung, damit du lernst, dies selbstständig herauszufinden. (Außerdem kann ich nicht alle Formatspezifizierer auswendig und müsste selber nachgucken :p )



  • SeppJ schrieb:

    (Außerdem kann ich nicht alle Formatspezifizierer auswendig und müsste selber nachgucken :p )

    Die Spezifier gehen ja noch. Gerade bei Fließkommazahlen ist das wie abc.
    Aber die ganzen Modifier ...



  • Ok, danke :).

    Dafür hab ich hier ja so ein Buch :D.

    Und stimmt, %f ist für double ausgeben und %lf ist bei scanf bzw. fscanf für double einlesen.

    Wir haben immer bis jetzt %f auch für float genommen, im Buch steht eigentlich nichs von float bei der Ausgabe. Für float auch %f?

    Da bei %f oder %lf ja abgerundet wird, weil 0,000000xxx rauskommt könnte ich alles als Exponentialzahl ausgeben mit %e, oder ich mache ein extra printf nur für c_divi mit %e.

    Aber das Ergebnis der Division stimmt bzw. meine Funktion c_divi, oder?

    Warum wird da bei der Ausgabe abgerundet? Ist das einfach so?

    Der Wertebereich für double ist ja: -1.7*10^308 bis 1.7*10^308. Also theoretisch müsste da die Zahl 0.000000xxx drinnen sein?



  • printf gibt bei %f sechs Nachkommastellen aus. 5.2946270969590323e-016 fängt aber erst bei der 16 Nakommastelle an.

    Wenn du mehr Stellen haben willst, musst du die width und/oder .precision Attribute angeben. Z.B. %.32f
    Oder nimm %g. Das nimmt je nach Wert %f oder %e. Auch das kannst du mit den Attributen anpassen.



  • Oder man macht das: printf("%0.100f + j%0.100f",a.real,a.imag);

    dann sieht man die Zahlen trotzdem noch in Dezimal :). Natürlich nicht gleich 100 da dann nach der Zahl vielen Nullen kommen, aber so halt einstellen das es genau passt :).


Anmelden zum Antworten