Algorithm for (A + Bi) ^ n

3

I need to do a program that gives the formula: A + B * i ^ n You have to find the smallest value of n to be a real number

Since A and B are inputs and i is part of the complex numbers.

I have an outline:

#include <stdio.h>
#include <math.h>

int main(){
  int a,b,c,n;
  int I  = sqrt(-1);
  scanf("%d",&a);
  scanf("%d",&b);

  for(n=1;n<=30;n++){
    c = pow(a + (b * **I**),n);
    if (c==**Número Real**) 
      printf("Valor de N é: %d",n);         
      break;   
    }
    return 0;   
  }
}

Where is "Real Number" I do not know how to represent this codified and the Square Root of -1 would have to be i but an absurd number. And I need this i to do the equation.

    
asked by anonymous 01.04.2015 / 21:05

2 answers

8

In fact your doubt becomes more a mathematical concept than a programming concept. To work with complex powers use the trigonometric form or the Euler form. No need to worry about the value of "i", since there is, in mathematics itself, notation that does not use it, as (real, imaginary) notation that treats the number as an ordered pair of the complex plane. The "i" is a representation that separates the real part from the complex, does not need to be worked on.

Code: (answer for (a + b * i) ^ n) Comments in the code explain (assuming n real):

#include <stdio.h> 
#include <math.h> 

#define PI 3.1415926535

/* Estrutura para forma complexa cartesiana */
typedef struct complexCart {

    double real;
    double imaginario;

} ComplexCart; 

/* Estrutura para forma complexa trigonométrica */
typedef struct complexTrig {

    double raio;
    double angulo;

} ComplexTrig;

/* Converte complexo cartesiano para trigonométrico */
ComplexTrig converterTrig(ComplexCart);

/* Converte complexo trigonométrico para cartesiano*/
ComplexCart converterCart(ComplexTrig);

int main(void)
{
    /* Variável que irá armazenar a menor potência 
       necessária. */
    double menorPot;

    /* Variável "cart" irá guardar número na forma
       cartesiana: a + bi, já "trig" na forma trigono-
       métrica: r(cos(Angulo) + i sen(Angulo)). 
       Vale notar que basta trabalhar com os parâmetros 
       em cada um desses casos, por exemplo, para trabalhar
       com dados cartesianos basta (a, b) e trigonométrico sim-
       plesmente (r, Angulo) */
    ComplexCart cart;
    ComplexTrig trig;

    printf("\nDigite um número imaginário da forma a + bi: ");
    /* Espera receber o número da forma cartesiana. 
       Ex: -2 + 3i, ou 2 + -3i (imaginária negativa) */
    scanf("%lf + %lfi", &cart.real, &cart.imaginario);

    /* Converte para forma trigonométrica, essa é mais fácil de lidar 
       com potências, raízes, divisões e multiplicações. Também poderia 
       ser utilizada a forma de Euler */
    trig = converterTrig(cart);

    /* Mostra a forma trigonométrica com o ângulo em radianos: Somente quando
       for exibir o resultado se preocupe com a forma de escrita complexa! */
    printf("O número em forma trigonométrica (em radianos): z = %.2f(cos(%.2f)   + i sen(%.2f))\n", 
         trig.raio, trig.angulo, trig.angulo);  

    /* Com o ângulo calcula-se a menor potência necessária 
       para que a parte do seno zere, ou seja, quando o ângulo é */
    menorPot = PI / (trig.angulo) ;

    /* Mostra a potência e o ângulo final quando a forma trigonométrica
       possui tal ângulo. */
    printf("A menor potência para tornar o número somente real é: %.2f\n", menorPot);
    printf("Ângulo da forma trigonométrica: %.2f rad\n", (trig.angulo) * menorPot); 

    /* Reatribui à forma trigonométrica o valor com a potência, ou seja,
       a forma já será com o valor elevado à potência */
    trig.raio = pow((trig.raio), menorPot);
    trig.angulo = (trig.angulo) * menorPot;

    /* Converte a forma trigonométrica da potência à forma cartesiana */
    cart = converterCart(trig);

    /* Mostra o resultado trigonométrico, o seno do ângulo dev ser zero. 
       Verifique!*/
    printf("Forma trigonométrica z^(%.2f) = %.2f(cos(%.2f) + i sen(%.2f))\n",
        menorPot, trig.raio, trig.angulo, trig.angulo); 

    /* Aqui, na fomra cartesiana, por garantia mostra-se a parte imaginária, 
       que deverá sempre ser zero. */  
    printf("Forma cartesiana z^(%.2f) = %.2f + %.2f i\n\n", menorPot, cart.real,
        cart.imaginario);  

    return 0;
}

/* Implementações dos Protótipos. */
ComplexTrig converterTrig(ComplexCart dadoCart){

    ComplexTrig dadoTrig;

    dadoTrig.raio = sqrt( (dadoCart.real) * (dadoCart.real) +
        (dadoCart.imaginario) * (dadoCart.imaginario) );

    if(dadoCart.real != 0)  
        dadoTrig.angulo = atan( (dadoCart.imaginario) / (dadoCart.real));

    else 
        dadoTrig.angulo = PI / 2;

    return dadoTrig;
}

ComplexCart converterCart(ComplexTrig dadoTrig){

    ComplexCart dadoCart;

    dadoCart.real = (dadoTrig.raio) * cos(dadoTrig . angulo);
    dadoCart.imaginario = (dadoTrig.raio) * sin(dadoTrig.angulo);

    return dadoCart;
}

In the example above I used structures to better idealize (and demonstrate union) the complex pair. (It could have been done with 4 independent doubles, but with structure it is easier to visualize). The rest is math. Remember that whenever you work with complex numbers it is not necessary (most of the time) to deal with the VALUE of i, just work as a usual ordered pair, but subject to a certain algebra (I will not comment because it leaves the scope of the site ).

    
03.04.2015 / 23:17
3

Rafael's answer solves the problem in the smartest way (converting the complex to a trigonometric representation), but I think it would be interesting to show that it is not difficult to solve the problem in a way similar to what you already have. p>

All you have to do is implement the multiplication yourself instead of trying to want complex numbers in C and using the * native operator.

If you have two numbers X = a + b*i and Y = c + d*i the X*Y product will be

X*Y =
(a + b*i)(c + d*i)        =  (por distributividade)
ac + ad*i + bc*i + ad*i^2 = (por i^2 = -1)
(ac - bd) + (ad + bc)*i

We can represent this in C by using a pair of integers (a,b) to represent the complex number a + b*i .

typedef struct {
    int r; /* parte real */
    int i; /*parte imaginaria */
} Complex;

And we can implement operations on the complex type we just created as simple functions rather than operators.

Complex addComplex(Complex x, Complex y){
    Complex z;
    z.r = x.r + y.r;
    z.i = x.i + y.i
    return z;
}

Complex multComplex(Complex x, Complex y){
     Complex z;
     z.r = x.r*y.r - x.i*y.i;
     z.i = x.r+y.i + x.i+y.r;
     return z;
}

After that, it's easy to implement a version that works from the code you already have:

int main(){

    Complex x;
    scanf("%d",&x.r);
    scanf("%d",&x.i);

    Complex x_n = {1, 0};
    for(int n=1;n<=30;n++){
        x_n = multComplex(x_n, x);
        if (x_n.i == 0){
            printf("Valor de N é: %d",n);         
            break;
        }
    }
    return 0;
}

One advantage of writing the code this way is that all accounts are made up of integers instead of doubles, which avoids rounding problems. However, the x_n fields will underflow after a few iterations due to the exponential growth of x_n "radius". A more robust version of this code should represent complex numbers with a data type for "infinite precision integers" instead of using int .

    
04.04.2015 / 17:59