# Thread: Structs and functions help

1. ## 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. 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.

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

5. 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,"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};

/***************************************/
/***************************************/

/* 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   */

/*   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);
return !errors;
}

{
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];

if (!equal_complex(result,correct)) {
if (!errors) {
errors = 1;
}
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 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_subtract(char *err_messages);

int test_multiply(char *err_messages);

int test_divide(char *err_messages);

#endif```

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

7. When i ran that simple program i got:
0.000000 2.000000

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