Search code examples
cstructcomplex-numberscomplex.h

How to read complex number using complex.h in C?


I want to read from a file two complex numbers

(1.1,2) (1.7,3.14)

In the beginning I do this

struct Num { double Re; 
                    double Im; 
                };

typedef struct Num zesp;

zesp readZ(FILE *wp)
{
    char c;
    zesp z;
    assert(fscanf(wp,"%c%lg%c%lg%c%c",&c,&z.Re,&c,&z.Im,&c,&c));

    return z;
}

But now I get a new task, my teacher said that I should use complex.h to read, write, etc. instead of using my type zesp

First I initialize two complex numbers

    double complex c1;
    double complex c2;

Then I know that normally I will give them value by writing this

double complex z1 = 2.6 + 3.1*I

But how to do this by reading from a file?

(1.1,2) (1.7,3.14)

Edit: Numbers are stored like that

(1.1,2) (1.7,3.14) (2.71,-15)
(4,3.21) (6,7.89)
(10,45)

parenthesis and space between complex numbers


Solution

  • complex.h does not declare or define:

    • any facilities for input or output,
    • any facilities for conversion between strings and complex numbers, or
    • any means of accessing an lvalue for the parts of a complex number, which would be necessary to store values in those parts via a scanf or similar function.

    Thus, it is unclear what your teacher meant by directing you to use complex.h to read complex numbers. When writing, we can use creal and cimag to obtain the values of the parts, and those are declared in complex.h.

    There are means to access lvalues for the parts of a complex number. C 6.2.5 13 says “Each complex type has the same representation and alignment requirements as an array type containing exactly two elements of the corresponding real type; the first element is equal to the real part, and the second element to the imaginary part, of the complex number.” Although this statement lacks some formal niceties, we can tell, by analogy to other wording in the standard, that it intends to tell us that we can convert a pointer to complex double to a pointer to double [2] and use that to access the parts. Thus, we can do:

    #include <complex.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
        complex double x;
        double *y = * (double (*)[2]) &x;
        if (2 != scanf("(%lg,%lg)", &y[0], &y[1]))
        {
            fputs("Error, scanf failed.\n", stderr);
            exit(EXIT_FAILURE);
        }
        printf("Read %g + %g i.\n", creal(x), cimag(x));
    }