#include <stdio.h>

#define EPSILON .0000001

/*
  Prototipos e definicoes necessarias para a manipulacao
  de numeros complexos, do livro de Sedgewick (veja abaixo)
 */

typedef struct { double Re; double Im; } Complex;
Complex COMPLEXinit(double, double);
 double Re(Complex);
 double Im(Complex);
Complex COMPLEXmult(Complex, Complex);

/* Codigo adicionado */

Complex COMPLEXdiv(Complex, Complex);
Complex COMPLEXdiff(Complex, Complex);
Complex COMPLEXadd(Complex, Complex);
Complex COMPLEXconj(Complex);

   void COMPLEXprint(Complex);
   void COMPLEXscan(Complex *);

    int COMPLEXclose(Complex, Complex);

/* Fim do codigo de Sedgewick */

int main()
{
    Complex z, t, tt, um;

    COMPLEXscan(&z);

    COMPLEXprint(z);
    printf("\n");
    COMPLEXprint(COMPLEXmult(z,z));
    printf("\n");
    COMPLEXprint(COMPLEXdiv(COMPLEXmult(z,z),z));
    printf("\n");

    um = COMPLEXinit(1,0);

    t = COMPLEXdiff(um, COMPLEXmult(z,z));
    COMPLEXprint(t);
    printf("\n");

    t = COMPLEXdiff(um, z);
    tt = COMPLEXadd(um, z);
    COMPLEXprint(COMPLEXmult(t,tt));
    printf("\n");

    return 0;
}

/*
  Implementacoes das funcoes para manipulacao de numeros
  complexos.  Este codigo 'e de um excelente livro, adequado
  para um segundo (e terceiro) curso de programacao:

    This code is from "Algorithms in C, Third Edition," 
    by Robert Sedgewick, Addison Wesley Longman, 1998." 
    (com algumas edicoes e adicoes)
 */

Complex COMPLEXinit(double Re, double Im)
  { Complex t; t.Re = Re; t.Im = Im; return t; }
double Re(Complex z)
  { return z.Re; }
double Im(Complex z)
  { return z.Im; }
Complex COMPLEXmult(Complex a, Complex b)
  { Complex t; 
    t.Re = a.Re*b.Re - a.Im*b.Im; 
    t.Im = a.Re*b.Im + a.Im*b.Re; 
    return t; 
  }

/* Fim do codigo de Sedgewick */

/* Codigo adicionado */

Complex COMPLEXdiv(Complex a, Complex b)
{
  Complex t;
  double r = b.Re*b.Re + b.Im*b.Im;
  t.Re = (a.Re*b.Re + a.Im*b.Im)/r;
  t.Im = (-a.Re*b.Im + a.Im*b.Re)/r;
  return t; 
}

Complex COMPLEXdiff(Complex z, Complex w)
{
  Complex t;
  t.Re=z.Re-w.Re;
  t.Im=z.Im-w.Im;
  return t;
}

Complex COMPLEXadd(Complex z, Complex w)
{
  Complex t;
  t.Re=z.Re+w.Re;
  t.Im=z.Im+w.Im;
  return t;
}

Complex COMPLEXconj(Complex z)
{
  Complex t;
  t.Re=z.Re;
  t.Im=-z.Im;
  return t;
}

void COMPLEXprint(Complex z)
{
  printf("%6.3f %6.3f", z.Re, z.Im);
}

void COMPLEXscan(Complex *z)
{
  scanf("%lf %lf", &((*z).Re), &((*z).Im));
}

int COMPLEXclose(Complex z, Complex zz)
{
  return
    (Re(COMPLEXdiff(z,zz)) < EPSILON)&&(-Re(COMPLEXdiff(z,zz)) < EPSILON)
    && 
    (Im(COMPLEXdiff(z,zz)) < EPSILON)&&(-Im(COMPLEXdiff(z,zz)) < EPSILON);
}
