VB .NET - Trabalhando com números Complexos


Recentemente precisei ajudar minha filha a resolver exercícios com números complexos e tive que recordar os conceitos sobre o assunto. Isso me levou a pesquisar sobre o tema e encontrei muitas referências sobre como trabalhar com números complexos.

Então eu pensei : "Porque não escrever um artigo sobre números complexos mostrando como trabalhar com eles na linguagem VB .NET ?"

Este artigo é o resultado da minha compilação dos artigos encontrados na web sobre o assunto.

Números complexos - Conceitos

Girolamo Cardano (1501-1576) esse é o cara que contribuiu para iniciar os estudos dos números complexos. Ele mostrou que era possível obter a solução para a equação do segundo grau : x2 – 10x +40 = 0 que possui raiz quadrada com número negativo.

Um número complexo é um número z que pode ser escrito na forma z = a + bi

onde : a e b são números reais e i é a unidade imaginária.

O conjunto dos números complexos, denominado C , contém o conjunto dos números reais.

representação : C = {z = b+ bi: a, b E R e i2 = -1}, onde R representa o conjunto dos números reais.

Números Complexos resumo:

Trabalhando com números complexos no Visual Basic

Após fazer um hiper resumo sobre os números complexos vamos mostrar como podemos trabalhar com números complexos usando a linguagem VB .NET.

Existem muitos maneiras de abordar o tratamento dos números complexos e eu vou mostrar algumas delas, as mais simples, e indicar outras opções que usam bibliotecas na forma de assembly DLL já prontas para serem usadas.

1- Realizando as operações básicas com números complexos usando uma classe

Neste projeto bem simples iremos realizar as 4 operações básicas com números complexos.

Abra o Visual Basic 2010 Express Edition e crie um novo projeto do tipo Windows Application com o nome NumerosComplexos;

No formulário padrão form1.vb vamos incluir, a partir da ToolBox, os controles Button, TextBox, GroupBox e Label definindo o leiaute conforme a figura abaixo:

Neste formulário o usuário deverá informar os valores para os coeficientes da parte real e da parte imaginária para os números complexos Z1 e Z2.

Após isso o sistema permite realizar as 4 operações básicas bastando para isso clicar no respectivo botão Calcular.

Para realizar os cálculos com os números complexos vamos criar uma classe via menu Project -> Add Class com o nome NumeroComplexo.vb e definir o código abaixo nesta classe:

Public Class NumeroComplexo

    Public Real As Double
    Public Imaginario As Double

    Public Sub New(ByVal ParteReal As Double, ByVal ParteImaginaria As Double)
        Me.Real = ParteReal
        Me.Imaginario = ParteImaginaria
    End Sub

    Public Sub New(ByVal numero As NumeroComplexo)
        Me.Real = numero.Real
        Me.Imaginario = numero.Imaginario
    End Sub

    Public Overrides Function ToString() As String
        Return Real & "+" & Imaginario & "i"
    End Function

    Public Shared Operator +(ByVal a As NumeroComplexo, ByVal b As NumeroComplexo) As NumeroComplexo
        Return New NumeroComplexo(a.Real + b.Real, a.Imaginario + b.Imaginario)
    End Operator

    Public Shared Operator -(ByVal a As NumeroComplexo, ByVal b As NumeroComplexo) As NumeroComplexo
        Return New NumeroComplexo(a.Real - b.Real, a.Imaginario - b.Imaginario)
    End Operator

    Public Shared Operator *(ByVal a As NumeroComplexo, ByVal b As NumeroComplexo) As NumeroComplexo
        Return New NumeroComplexo(a.Real * b.Real - a.Imaginario * b.Imaginario, a.Real * b.Imaginario + a.Imaginario * b.Real)
    End Operator

    Public Shared Operator /(ByVal a As NumeroComplexo, ByVal b As NumeroComplexo) As NumeroComplexo
        Return a * Reciprocal(b)
    End Operator

    Public Shared Function Reciprocal(ByVal a As NumeroComplexo) As NumeroComplexo
        Dim divisor As Double

        divisor = a.Real * a.Real + a.Imaginario * a.Imaginario

        If (divisor = 0.0#) Then
            Throw New DivideByZeroException
        End If

        Return New NumeroComplexo(a.Real / divisor, -a.Imaginario / divisor)
    End Function
End Class

Neste código estamos definindo a sobrecarga dos operadores. A sobrecarga de operador é a capacidade de definir procedimentos para um conjunto de operadores em um determinado tipo. Isto permite escrever código mais intuitivo e mais legível. Os operadores podem ser definidas em que sua classe ou estrutura são os seguintes:

Na sobrecarga estamos usando a palavra-chave Operator ao invés de Function. A palavra-chave Operator é usada para declarar um operador em uma declaração de classe ou struct.

A seguir temos o código do formulário onde para cada evento Click criamos a instância dos números complexos e realizarmos os cálculos exibindo o resultado:

Public Class Form1

    Dim z1 As NumeroComplexo
    Dim z2 As NumeroComplexo

    Dim resultado As NumeroComplexo

    Dim z1_r As Double
    Dim z1_i As Double
    Dim z2_r As Double
    Dim z2_i As Double

    Private Sub btnAdicao_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdicao.Click
        If validar() Then
            Dim z1_r = Convert.ToDouble(Z1_Real.Text)
            Dim z1_i = Convert.ToDouble(Z1_Imaginario.Text)
            Dim z2_r = Convert.ToDouble(Z2_Real.Text)
            Dim z2_i = Convert.ToDouble(Z2_Imaginario.Text)
            z1 = New NumeroComplexo(z1_r, z1_i)
            z2 = New NumeroComplexo(z2_r, z2_i)

            resultado = z1 + z2

            txtResultadoAdicao.Text = resultado.ToString

        End If
    End Sub
    Private Sub btnSubtracao_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSubtracao.Click
        If validar() Then
            Dim z1_r = Convert.ToDouble(Z1_Real.Text)
            Dim z1_i = Convert.ToDouble(Z1_Imaginario.Text)
            Dim z2_r = Convert.ToDouble(Z2_Real.Text)
            Dim z2_i = Convert.ToDouble(Z2_Imaginario.Text)
            z1 = New NumeroComplexo(z1_r, z1_i)
            z2 = New NumeroComplexo(z2_r, z2_i)

            resultado = z1 - z2

            txtResultadoSubtracao.Text = resultado.ToString

        End If
    End Sub

    Private Sub btnMultiplicacao_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMultiplicacao.Click
        If validar() Then
            Dim z1_r = Convert.ToDouble(Z1_Real.Text)
            Dim z1_i = Convert.ToDouble(Z1_Imaginario.Text)
            Dim z2_r = Convert.ToDouble(Z2_Real.Text)
            Dim z2_i = Convert.ToDouble(Z2_Imaginario.Text)
            z1 = New NumeroComplexo(z1_r, z1_i)
            z2 = New NumeroComplexo(z2_r, z2_i)

            resultado = z1 * z2

            txtResultadoMultiplicacao.Text = resultado.ToString

        End If
    End Sub
    Public Function validar() As Boolean
        If Z1_Real.Text = String.Empty Or Z1_Imaginario.Text = String.Empty Or Z2_Real.Text = String.Empty Or Z2_Imaginario.Text = String.Empty Then
            MessageBox.Show("Informe os valores válidos para os números complexos...", "Inválido.", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return False
        Else
            Return True
        End If
    End Function

    Private Sub Z1_Real_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) 
Handles Z1_Real.KeyPress, Z1_Imaginario.KeyPress, Z2_Real.KeyPress, Z2_Imaginario.KeyPress
        If Not Char.IsNumber(e.KeyChar) And Not e.KeyChar = vbBack And Not e.KeyChar = "." And Not e.KeyChar = "," And Not e.KeyChar = "-" Then
            e.Handled = True
        End If
    End Sub

    Private Sub btnDivisao_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDivisao.Click
        If validar() Then
            Dim z1_r = Convert.ToDouble(Z1_Real.Text)
            Dim z1_i = Convert.ToDouble(Z1_Imaginario.Text)

            Dim z2_r = Convert.ToDouble(Z2_Real.Text)
            Dim z2_i = Convert.ToDouble(Z2_Imaginario.Text)

            z1 = New NumeroComplexo(z1_r, z1_i)
            z2 = New NumeroComplexo(z2_r, z2_i)

            resultado = z1 / z2

            txtResultadoDivisao.Text = resultado.ToString

        End If
    End Sub

End Class

Executando o projeto iremos obter:

2-) Usando os novos recursos do namespace System.Numerics

Eu deixei para o final para falar sobre a nova classe Complex do namespace System.Numerics disponível a partir da versão 4.0 da plataforma .NET.

A classe Complex representa números complexos e permite realizar operações aritméticas com números complexos.

Para poder usar o namespace System.Numerics temos que referenciar a library no projeto. Para isso no menu Project clique em Add Reference e na guia .NET selecione System.Numerics:

Vamos incluir um novo formulário no projeto via menu Project -> Add Windows Forms e aceitando o nome padrão form2.vb;

Após isso inclua a declaração no formulário: Imports System.Numerics

Vamos criar a interface no form2.vb aproveitando o mesmo leiaute da formulário form1.vb e acrescentando os cálculos para o conjuga do número complexo e da raiz quadrada. Abaixo temos o leiaute do formulário :

O código do formulário é dado a seguir:

Imports System.Numerics
Public Class Form2

    Dim z1 As Complex
    Dim z2 As Complex

    Dim resultado As Complex

    Dim z1_r As Double
    Dim z1_i As Double
    Dim z2_r As Double
    Dim z2_i As Double

    Private Sub btnAdicao_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        If validar() Then
            montaNumerosComplexos()
            resultado = z1 + z2
            txtResultadoAdicao.Text = resultado.ToString
        End If
    End Sub
    Private Sub btnSubtracao_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        If validar() Then
            montaNumerosComplexos()
            resultado = z1 - z2
            txtResultadoSubtracao.Text = resultado.ToString
        End If
    End Sub

    Private Sub btnMultiplicacao_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        If validar() Then
            montaNumerosComplexos()
            resultado = z1 * z2
            txtResultadoMultiplicacao.Text = resultado.ToString
        End If
    End Sub

    Private Sub btnDivisao_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        If validar() Then
            montaNumerosComplexos()
            resultado = z1 / z2
            txtResultadoDivisao.Text = resultado.ToString
        End If
    End Sub
    Private Sub btnCalcularConjugados_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalcularConjugados.Click
        If validar() Then
            montaNumerosComplexos()
            Dim conjugado1 As Complex = Complex.Conjugate(z1)
            Dim conjugado2 As Complex = Complex.Conjugate(z2)
            txtConjugadoZ1.Text = conjugado1.ToString
            txtConjugadoZ2.Text = conjugado2.ToString
        End If
    End Sub

    Private Sub btnCalcularRaizQuadradaZ1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalcularRaizQuadradaZ1.Click
        If validar() Then
            montaNumerosComplexos()
            resultado = Complex.Sqrt(z1)
            txtRaizQuadradaZ1.Text = resultado.ToString
        End If
    End Sub

    Public Function validar() As Boolean
        If Z1_Real.Text = String.Empty Or Z1_Imaginario.Text = String.Empty Or Z2_Real.Text = String.Empty Or Z2_Imaginario.Text = String.Empty Then
            MessageBox.Show("Informe os valores válidos para os números complexos...", "Inválido.", MessageBoxButtons.OK, MessageBoxIcon.Error)
            Return False
        Else
            Return True
        End If
    End Function
    Private Sub Z1_Real_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs)
 Handles Z1_Real.KeyPress, Z1_Imaginario.KeyPress, Z2_Real.KeyPress, Z2_Imaginario.KeyPress
        If Not Char.IsNumber(e.KeyChar) And Not e.KeyChar = vbBack And Not e.KeyChar = "." And Not e.KeyChar = "," And Not e.KeyChar = "-" Then
            e.Handled = True
        End If
    End Sub

    Private Sub montaNumerosComplexos()
        z1_r = Convert.ToDouble(Z1_Real.Text)
        z1_i = Convert.ToDouble(Z1_Imaginario.Text)
        z2_r = Convert.ToDouble(Z2_Real.Text)
        z2_i = Convert.ToDouble(Z2_Imaginario.Text)
        z1 = New Complex(z1_r, z1_i)
        z2 = New Complex(z2_r, z2_i)
    End Sub

    Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
        Me.Close()
    End Sub
    Public Sub LimparTextBox()
       
    End Sub

    Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
        LimparTextBox()
    End Sub
End Class

A diferença é que neste formulário estamos usando a classe Complex e seus métodos para efetuar os cálculos sendo que o resultado é feito usando não representação algébrica mas na forma de coordenadas: ( a, b ) onde => ( a, b ) a + bi

Poderíamos implementar outros cálculos e se você desejar fazer isso veja as referências para os métodos da classe Complex.

Se você desejar pode também usar as bibliotecas de terceiros vou apontar uma que é grátis :

  1. http://www.codeproject.com/KB/dotnet/complex_math.aspx

Basta acessar o link, baixar a DLL e consultar a documentação.

Bem, só faltou eu mostrar uma versão para tratamento de números complexos na versão do Visual Basic 6.

Pegue o projeto completo aqui: NumerosComplexos.zip

Rom 8:12 Portanto, irmãos, somos devedores, não à carne para vivermos segundo a carne;
Rom 8:13
porque se viverdes segundo a carne, haveis de morrer; mas, se pelo Espírito mortificardes as obras do corpo, vivereis.

Rom 8:14
Pois todos os que são guiados pelo Espírito de Deus, esses são filhos de Deu

Referências:

José Carlos Macoratti