Thread: Structs and functions help

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    15

    Structs and functions help

    I am working on a function for my project that formats the output of complex(imaginary) numbers, but when I run it, its not being formatted as i thought it would be.
    the struct being used is:
    Code:
    typedef struct {
      double re;
      double im;
    } complex;
    the function i have written for this so far is:
    Code:
    void output_complex(FILE *outf,complex z)
    {
       if(z.im == 0)
       {
          fprintf(outf,"%d", z.re);
       }
       if(z.re == 0)
       {
          if(z.im == 1)
          {
    	 fprintf(outf,"i"); 
          }
          fprintf(outf,"%di", z.im);
       }
        if(z.im == 1)
       {
          fprintf(outf,"%d + i", z.re);
       }
       if(z.im < 0)
       {
          if(z.im == -1)
          {
             z.im *= -1;
    	 fprintf(outf,"%d - i", z.re);
          }
          z.im *= -1;  
          fprintf(outf,"%d - %di", z.re, z.im);
       }
       fprintf(outf,"%d + %di", z.re, z.im);
    }
    and there is this program that checks to see if the expected output is the same as the output of the function and this is what I got when I ran it for this function:
    Output Function Errors:
    expected: 1 + 2i
    actual: 0 + 1072693248i
    expected: 1 + 2i
    actual: 0 + 1072693248i

    what am I doing wrong?

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Floating point numbers are inaccurate. Also, 0 is not the same as 0.0. Furthermore, equality tests on floats are really never a good idea. You need to probably be going something like:
    Code:
    if( f.im < 0.00001 && f.im > -0.999999 )
    Or something like that. Honestly I never use floating point numbers when I can avoid it. You are also using %d instead of %f.

    If you want integers, just use integers.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Apr 2011
    Posts
    15
    I replaced the %d's with %lf's, and now for the output function errors i am getting:
    Output Function Errors:
    expected: 1 + 2i
    actual: 1.000000 + 2.000000i
    expected: 1 + 2i
    actual: 1.000000 + 2.000000i

    is there a way for me to get rid of the extra zeros, but still have the ability for numbers to go as far as the zeros go currently past the decimal point? the assignment gave us a function and says you cannot change it, which means double has to be used

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You haven't actually provided us with a working example.
    Code:
    #include<stdio.h>
    int main( void )
    {
        struct {
            double re;
            double im;
        } c;
    
        c.re = 0;
        c.im = 2;
    
        printf( "%f %f\n", c.re, c.im );
    
        return 0;
    }
    What's that give you?

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Apr 2011
    Posts
    15
    Given:
    main.c
    Code:
    /**************************************/
    /*             main.c                 */
    /*     DO NOT MODIFY THIS FILE        */
    /**************************************/
    
    #include "tests.h"
    #include "complex.h"
    
    int main()
    {
       FILE *errF = NULL;
       FILE *reportF = NULL;
       char errBuffer[2000] = {0};
    
       printf("\nWelcome to the Complex Number Module Test Program\n\n");
       printf("Tests results can be found in file testResults\n");
       printf("and error reports in file errorFile\n\n");
    
       if ((errF = fopen("errorFile","w")) == NULL) {
          printf("Unable to open errorFile for writing\n");
          exit(1);
       }
    
       if ((reportF = fopen("testResults","w")) == NULL) {
          printf("Unable to open testResults for writing\n");
          exit(1);
       }
      
       fprintf(reportF,"\n\t\tComplex Number Test Report\n\n");
    
       fprintf(reportF,"output_complex:     %s\n",test_output(errBuffer)? "pass" : "fail");
       fprintf(reportF,"add_complex:        %s\n",test_add(errBuffer)? "pass" : "fail");
       fprintf(reportF,"subtract_complex:   %s\n",test_subtract(errBuffer)? "pass" : "fail");
       fprintf(reportF,"multiply_complex:   %s\n",test_multiply(errBuffer)? "pass" : "fail");
       fprintf(reportF,"divide_complex:     %s\n",test_divide(errBuffer)? "pass" : "fail");
    
       fclose(reportF);
    
       fprintf(errF,"%s",errBuffer);
    
       printf("Normal termination\n\n");
    
       return 0;
    }
    complex.c:
    Code:
    #include "complex.h"
    
    const complex ZERO = {0.0,0.0};
    
    /***************************************/
    /*    ALREADY IMPLEMENTED FUNCTIONS    */
    /***************************************/
    
    /* utility function */
    int good(double im, char op, char ch)
    {
      if (ch != 'i')
        return 0;
    
      if (op != '+' && op != '-')
        return 0;
    
      if (im < 0)
        return 0;
    
      return 1;
    }
    
    complex input_complex(FILE *infile)
    {
      complex z = {0,0};
      double re = 0, im = 0;
      char op, ch;
    
      fscanf(infile,"%lf %c%lf%c",&re,&op,&im,&ch);
    
      if (infile != stdin && !good(im,op,ch)) {
        printf("Improperly formed complex number in input file; goodbye\n");
        exit(1);
      }
    	
      while(!good(im,op,ch)) {
        printf("Illegal input for complex number; try again\n");
        fscanf(infile,"%lf %c%lf%c",&re,&op,&im,&ch);
        
      }
      
      z.re = re;
      if (op == '+')
        z.im = im;
      else
        z.im = -im;
      
      return z;
    }
    
    int equal_complex(complex z, complex w)
    {
      return z.re == w.re && z.im == w.im;
    }
    
    double mag_squared(complex z)
    {
      return z.re*z.re + z.im*z.im;
    }
    
    complex scalar_multiple(double c, complex z)
    {
      complex w = ZERO;
      w.re = c*z.re;
      w.im = c*z.im;;
      return w;
    }
    
    complex conjugate(complex z)
    {
      complex w = ZERO;
      w.re = z.re; 
      w.im = -z.im;
      return w;
    }
    
    /*****************************************************************/
    /* FUNCTIONS FOR YOU TO IMPLEMENT - JUST STUBS FOR NOW           */
    /*****************************************************************/
    
    
    /* Output Function Errors:
       expected: 1 + 2i
       actual: 0 + 1072693248i
       expected: 1 + 2i
       actual: 0 + 1072693248i*/
    void output_complex(FILE *outf,complex z)
    {
       if(z.im == 0)
       {
          fprintf(outf,"%lf", z.re);
       }
       if(z.re == 0)
       {
          if(z.im == 1)
          {
    	 fprintf(outf,"i"); 
          }
          fprintf(outf,"%lfi", z.im);
       }
        if(z.im == 1)
       {
          fprintf(outf,"%lf + i", z.re);
       }
       if(z.im < 0)
       {
          if(z.im == -1)
          {
             z.im *= -1;
    	 fprintf(outf,"%lf - i", z.re);
          }
          z.im *= -1;  
          fprintf(outf,"%lf - %lfi", z.re, z.im);
       }
       fprintf(outf,"%lf + %lfi", z.re, z.im);
    }
    complex.h
    Code:
    /***************************/
    /*     file complex.h      */
    /***************************/
    #include <stdio.h>
    #include <stdlib.h>
    
    #ifndef _COMPLEX_H_
    #define _COMPLEX_H_
    
    typedef struct {
      double re;
      double im;
    } complex;
    
    /***********************************************************************/
    /* You do not need to implement or test the next two functions         */
    /* Their implementations are already in complex.c and have been tested */
    /***********************************************************************/
    
    /* reads in a complex number from input and returns that value */
    complex input_complex(FILE *infile);
    
    /* returns 1 if z = w and 0 otherwise */
    int equal_complex(complex z, complex w);
    
    
    
    /*****************************************************************/
    /* The remaining functions are for you to implement in complex.c */
    /*****************************************************************/
    
    /* print z to file outf in the correct format      */
    /* you may assume outf has been opened for writing */
    void output_complex(FILE *outf,complex z);
    
    /*  compute and return the square of |z|  */
    /* DO NOT USE SQUARE ROOT; NOT NEEDED!    */
    double mag_squared(complex z);
    
    /*   compute and return cz   */
    complex scalar_multiple(double c, complex z);
    
    /* compute and return the conjugate of z */
    complex conjugate(complex z);
    
    /*   compute and return z+w   */
    complex add_complex(complex z, complex w);
    
    /*   compute and return z-w   */
    complex subtract_complex(complex z, complex w);
    
    /*   compute and return z*w   */
    complex multiply_complex(complex z, complex w);
    
    /*   compute and return z/w   */
    complex divide_complex(complex z, complex w);
    
    #endif
    tests.c
    Code:
    /**************************************/
    /*            tests.c                 */
    /*     DO NOT MODIFY THIS FILE        */
    /**************************************/
    
    #include "tests.h"
    #include "complex.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    static const complex ZERO = {0.0,0.0};
    
    int test_output(char * err_messages)
    {
       complex test_entries[OUTPUT_COUNT] = OUTPUT_DATA;
       const char * correctStrings[OUTPUT_COUNT] =  OUTPUT_CORRECT;
       int i = 0, errors = 0;
       char buffer[30] = {0};
       char temp[50] = {0};
    
       FILE * outputF = fopen("complex.out","w");
       if (outputF == NULL) {
          printf("Unable to open complex.out for outputting complex numbers\n");
          return 0;
       }
    
       for(i = 0; i < OUTPUT_COUNT; i++) {
          output_complex(outputF,test_entries[i]);
          fprintf(outputF,"\n");
       }
    
       fclose(outputF);
    
       if ((outputF = fopen("complex.out","r")) == NULL) {
          printf("Unable to reopen complex.out for reading\n");
          return 0;
       }
    
       for(i = 0; i < OUTPUT_COUNT; i++) {
          fgets(buffer,30,outputF);
          buffer[strlen(buffer)-1] = 0;
    
          if (strcmp(buffer,correctStrings[i]) != 0) {
    	 if (!errors) {
    	    sprintf(err_messages,"%s\n\nOutput Function Errors:\n",err_messages);
    	    errors = 1;
    	 }
    	 sprintf(err_messages,"%sexpected: %s\nactual: %s\n",err_messages,
    		 correctStrings[i],buffer);
          }
       }
       fclose(outputF);
       unlink("complex.out");
       return !errors;
    }
    
        
    int test_add(char * err_messages)
    {
       complex left_args[ADD_COUNT] = ADD_LEFT_ARGS;
       complex right_args[ADD_COUNT] = ADD_RIGHT_ARGS;
       complex corrects[ADD_COUNT] = ADD_CORRECT;
       complex computed[ADD_COUNT] = {ZERO};
       complex left = ZERO, right = ZERO, correct = ZERO, result = ZERO;
    
       int i = 0, errors = 0;
    
       for(i = 0; i < ADD_COUNT; i++) {
          left = left_args[i];
          right = right_args[i];
          correct = corrects[i];
          result = add_complex(left,right);
    
          if (!equal_complex(result,correct)) {
    	 if (!errors) {
    	    strcat(err_messages,"\n\nAdd Errors:\n");
    	    errors = 1; 
    	 }
    	 sprintf(err_messages,"%s(%.2f,%.2f)+(%.2f,%.2f)\nreceived (%.2f,%.2f), correct (%.2f,%.2f)\n\n",
    		 err_messages,left.re,left.im,right.re,right.im,result.re,result.im,
    		 correct.re,correct.im);
          }
       }
       return !errors;
    }
    tests.h
    Code:
    #ifndef _TESTS_H_
    #define _TESTS_H_
    
    #define OUTPUT_COUNT 2
    #define OUTPUT_DATA {{1,2},{1,2}}
    #define OUTPUT_CORRECT {"1 + 2i","1 + 2i"}
    
    #define ADD_COUNT 2
    #define ADD_LEFT_ARGS  {{2,3},{2,3} }
    #define ADD_RIGHT_ARGS {{1,2},{1,2}}
    #define ADD_CORRECT {{3,5},{3,5}}
    
    #define SUBTRACT_COUNT 2
    #define SUBTRACT_LEFT_ARGS  {{2,3},{2,3} }
    #define SUBTRACT_RIGHT_ARGS {{1,2},{1,2}}
    #define SUBTRACT_CORRECT {{1,1},{1,1}}
    
    #define MULTIPLY_COUNT 2
    #define MULTIPLY_LEFT_ARGS  {{2,3},{2,3} }
    #define MULTIPLY_RIGHT_ARGS {{1,2},{1,2}}
    #define MULTIPLY_CORRECT {{-4,7},{-4,7}}
    
    #define DIVIDE_COUNT 2
    #define DIVIDE_LEFT_ARGS  {{2,3},{2,3} }
    #define DIVIDE_RIGHT_ARGS {{1,2},{1,2}}
    #define DIVIDE_CORRECT {{1.6,0.2},{1.6,0.2}}
    
    
    /*******************************************/
    /*  DO NOT MODIFY THE PROTOTYPES BELOW     */
    /*******************************************/
    
    int test_output(char *err_messages);
    
    int test_add(char *err_messages);
    
    int test_subtract(char *err_messages);
    
    int test_multiply(char *err_messages);
    
    int test_divide(char *err_messages);
    
    #endif

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    So what did you get in my example? If that prints fine for you, then your math is off some place. No one wants to compile hundreds of lines of code when a small 10 line example should do the trick.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Apr 2011
    Posts
    15
    When i ran that simple program i got:
    0.000000 2.000000

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Sounds like you have a math problem then. Start printing your values before and after function calls or math operations to make sure they're right.


    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. arrays, structs, dlls, functions...
    By albatroz00 in forum C Programming
    Replies: 2
    Last Post: 03-04-2011, 03:27 AM
  2. Structs, pointers and functions
    By osici in forum C Programming
    Replies: 2
    Last Post: 04-29-2009, 12:35 AM
  3. Pointers, structs, and functions, oh my!
    By funkydude9 in forum C++ Programming
    Replies: 8
    Last Post: 07-30-2003, 12:51 AM
  4. passing structs to functions?
    By Neildadon in forum C++ Programming
    Replies: 1
    Last Post: 12-13-2002, 04:31 PM
  5. probs with structs and functions
    By Unregistered in forum C Programming
    Replies: 10
    Last Post: 05-08-2002, 11:52 PM

Tags for this Thread