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



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



  • edit: den letzten Beitrag habe ich geschrieben bevor ich DirkBs Beitrag gelesen habe :D.

    Aber die funktion c_divi stimmt?



  • guest123 schrieb:

    Der Wertebereich für double ist ja: -1.7*10^308 bis 1.7*10^308.

    Der Wertebereich von double geht von -DBL_MAX bis DBL_MAX.

    guest123 schrieb:

    Also theoretisch müsste da die Zahl 0.000000xxx drinnen sein?

    Die unteren double Schranken gehen analog von -DBL_MIN bis DBL_MIN.



  • guest123 schrieb:

    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?

    Ja. Wegen der Default-argument-promotion bei variablen Parameterlisten.


Anmelden zum Antworten