C#
- Trabalhando com números racionais (Structs)
Neste artigo irei mostrar como podemos tratar números racionais criando uma classe e alguns métodos para realizar as operações básicas com números racionais.
Denominamos número racional o quociente de dois números inteiros (onde divisor tem que ser diferente de zero), ou seja, todo número que pode ser colocado na forma fracionária, em que o numerador e denominador são números inteiros.(o numerador aparece na parte superior da fração e do denominador na parte inferior.)
Representação : O conjunto dos números racionais é representando pela letra Q => Q = {m/n : m e n em Z, n diferente de zero}
O uso dos números racionais tem algumas vantagens sobre o uso de valores decimais.
A principal vantagem é a precisão. Com valores decimais, os erros de arredondamento podem ocorrer em pequenas quantidades, devido à maneira pela qual os valores são armazenados.
Isto pode ser visto no código do exemplo abaixo. Embora o valor inicial é dividido e depois multiplicado pelo mesmo número, o resultado não é o mesmo que o valor original. Se os números racionais fossem usados este problema de arredondamento não teriam sido introduzidos.
![]() |
Neste artigo vamos desenvolver uma estrutura(Struct) para tratar e manipular números racionais. A estrutura NumeroRacional poderia facilmente ser criada como uma classe. No entanto, neste caso uma estrutura é preferível visto que os números racionais exibem o comportamento de tipos de valor, em vez de tipos de referência.
Vamos portanto mostrar neste artigo como criar uma estrutura e definir seu construtor , propriedades e métodos e ainda rever alguns conceitos básicos dos números racionais.
Vamos começar com uma revisão de conceitos sobre estruturas.
O que são estruturas ?
Uma estrutura na linguagem C# é simplesmente uma composição de tipos de dados composta de elementos de outros tipos. Uma estrutura pode conter campos, métodos, constantes , construtores, propriedades, indexadores, operadores e mesmo outro tipos de estruturas.
Uma estrutura é considerado um Tipo por Valor e instâncias ou objetos de uma estrutura são criadas na memória STACK.
A seguir temos um exemplo de definição de uma estrutura no C#:
struct Clientes { string nome; string telefone; string email; } |
O código declara uma estrutura do tipo Public , por isso , pode ser colocado em
qualquer lugar do arquivo , exceto dentro de funções ou
rotinas.
Se a estrutura for Private podemos colocar o código dentro de
uma classe
ou módulo.
Feito isto é só usar a estrutura e criar um objeto do tipo Clientes em qualquer lugar do nosso código e atribuir as informações :
Clientes cliente; cliente.nome = "Macoratti"; cliente.email = "macoratti@yahoo.com"; |
Observe que estamos criando uma instância da estrutura sem usar o operador new mas também podemos usar este operador:
Clientes cliente = new
Clientes();
cliente.nome = "Macoratti";
cliente.email = "macoratti@yahoo.com";
Principais características de uma estrutura (struct):
Criando o projeto
Abra o Visual C# 2010 Express Edition e no menu File clique em New Project e escolha o template WIndows Forms Application com o nome TratandoNumerosRacionais e clique em OK;
A seguir no menu Project clique em Add New Item e selecione o template Class e informe o nome NumeroRacional.cs;
Vamos iniciar o código definido uma estrutura com o nome NumeroRacional:
struct NumeroRacional { } |
Vamos precisar criar duas propriedades na estrutura NumeroRacional. As propriedades são valores inteiros que representam o numerador e o denominador da fração do numero racional. Cada uma vai ser uma propriedade somente-leitura(read-only) de forma que a definição desses valores estará restrito ao construtor da estrutura.
Abaixo temos o código que cria as propriedades Numerador e Denominador somente-leitura. (note que definimos somente o get e não o set)
struct NumeroRacional { private int _numerador; private int _denominador; public int Numerador { get { return _numerador; } } public int Denominador { get { return _denominador; } } } |
Vamos agora definir um construtor que será responsável por definir os valores do numerador e denominador. Para isso adicione o seguinte código na estrutura:
public NumeroRacional(int numerador, int denominador) { if (denominador == 0) throw new ArgumentException("O denominador não pode ser igula a zero."); if (denominador < 0) { numerador *= -1; denominador *= -1; } _numerador = numerador; _denominador = denominador; ReducaoMenorTermo(); } |
O construtor faz o seguinte:
Um único número racional pode ser expresso através de muitas frações diferentes. Por exemplo, uma metade (½) pode ser escrita com uma numerador de dois e um denominador de quatro, ou como 4/8 ou 5/10. Cada uma destas representações é válida, mas geralmente é melhor exibir uma fração usando os seus menores termos. Isto significa que o numerador e denominador devem ser os menores números possíveis para o número racional.
Para reduzir uma fração a seus menores termos, o maior divisor comum (MDC) do numerador e denominador deve ser encontrado. Este é o maior número pelo qual ambas as partes da fração pode ser dividido, embora mantendo dois números inteiros. O método ReducaoMenorTermo chama um método adicional para determinar o MDC e divide o numerador e o denominador por este valor.
Inclua o método ReducaoMenorTermo na estrutura com o seguinte código:
private void ReducaoMenorTermo() { int maiorDivisorComun = NumeroRacional.Get_MDC(_numerador, _denominador); _numerador /= maiorDivisorComun; _denominador /= maiorDivisorComun; } |
O MDC de dois valores pode ser determinado usando o algoritmo euclidiano. Este algoritmo segue um processo iterativo. O primeiro valor é dividido pelo segundo valor e o resto é determinado. Se o resto é zero, o MDC é o primeiro valor. Se o resto é diferente de zero, o processo é repetido usando o termo segundo e o novo resto é calculado. (Para mais detalhes sobre esse assunto veja o link: Euclidean Algorithm.)
Para implementar o algoritmo, adicione método Get_MDC chamando-o iterativamente até que o máximo divisor comum seja determinado.
private static int Get_MDC(int termo1, int termo2) { if (termo2 == 0) return termo1; else return Get_MDC(termo2, termo1 % termo2); } |
Assim quando formos criar um novo número racional, o construtor já faz a redução da fração ao seu menor termo usando os dois métodos adicionados.
Definindo as operações com Números Racionais
Agora que a estrutura do número racional é capaz de tratar uma fração em seus menores termos, podemos adicionar as funções que irão realizar as operações aritméticas de adição, subtração, multiplicação e divisão.
Para conseguir isso, vamos sobrecarregar os operadores de +, -, * e / com novas versões que fornecem a funcionalidade correta para adição, subtração, multiplicação e divisão de frações. O primeiro a ser criado é o operador de adição.
Para adicionar dois números racionais juntos, definimos o seguinte código usando o operador sobrecarregado +:
![]() |
public static NumeroRacional operator +(NumeroRacional r1, NumeroRacional r2) { return new NumeroRacional((r1.Numerador * r2.Denominador) + (r2.Numerador * r1.Denominador), r1.Denominador * r2.Denominador); } |
Vamos repetir o processo desta vez sobrecarregando o operador - que será usado para subtração de dois números racionais:
![]() |
public static NumeroRacional operator -(NumeroRacional r1, NumeroRacional r2) { return new NumeroRacional((r1.Numerador * r2.Denominador) - (r2.Numerador * r1.Denominador), r1.Denominador * r2.Denominador); } |
Fazendo a mesma coisa para o operador * que representa a multiplicação de dois números racionais:
![]() |
public static NumeroRacional operator *(NumeroRacional r1, NumeroRacional r2) { return new NumeroRacional(r1.Numerador * r2.Numerador, r1.Denominador * r2.Denominador); } |
E por fim definimos para a sobrecarga do operador / que representa a divisão de dois números racionais:
![]() |
public static NumeroRacional operator /(NumeroRacional r1, NumeroRacional r2) { return new NumeroRacional(r1.Numerador * r2.Denominador, r1.Denominador * r2.Numerador); } |
Definindo a interface com o usuário e testando a estrutura NumeroRacional
No formulário form1.cs do projeto vamos definir a interface conforme mostra a figura abaixo:
![]() |
Após isso defina o seguinte código no formulário:
using System; using System.Windows.Forms; namespace TratandoNumerosRacionais { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnCalcular_Click(object sender, EventArgs e) { int nr1, dr1, nr2, dr2; //define a primeira fração nr1 = Convert.ToInt16(txt_num_r1.Text); dr1 = Convert.ToInt16(txt_den_r1.Text); //defina a segunda fração nr2 = Convert.ToInt16(txt_num_r2.Text); dr2 = Convert.ToInt16(txt_den_r2.Text); //cria os dois números racionais NumeroRacional r1 = new NumeroRacional(nr1, dr1); NumeroRacional r2 = new NumeroRacional(nr2, dr2); //fazendo os calculos NumeroRacional Adicao = r1 + r2; NumeroRacional Subtracao = r1 - r2; NumeroRacional Multiplicacao = r1 * r2; NumeroRacional Divisao = r1 / r2; //atribuindo os numeradores e denominadores //adicao txt_num_add.Text = Adicao.Numerador.ToString(); txt_den_add.Text = Adicao.Denominador.ToString(); //subtracao txt_num_sub.Text = Subtracao.Numerador.ToString(); txt_den_sub.Text = Subtracao.Denominador.ToString(); //multiplicacao txt_num_mul.Text = Multiplicacao.Numerador.ToString(); txt_den_mul.Text = Multiplicacao.Denominador.ToString(); //divisao txt_num_div.Text = Divisao.Numerador.ToString(); txt_den_div.Text = Divisao.Denominador.ToString(); } private void btnSair_Click(object sender, EventArgs e) { this.Close(); } } } |
No evento Click do botão de comando estamos definindo os numeradores e denominadores das duas frações e estamos usando o construtor e os métodos da estrutura NumeroRacional para realizar as operações de adição, subtração, multiplicação e divisão de dois números racionais expressos como frações.
Eu não estou realizando nenhuma validação no formulário por pura preguiça mas é recomendável que isso seja feito.
Executando o projeto e definindo duas frações quaisquer obtemos o seguinte resultado:
![]() |
Pegue o projeto completo
aqui: TratandoNumerosRacionais.zip
1Ts 1:6
E vós vos tornastes imitadores nossos e do Senhor, tendo recebido a palavra em muita tribulação, com gozo do Espírito Santo.1Ts 1:7
De sorte que vos tornastes modelo para todos os crentes na Macedônia e na Acaia.1Ts 1:8
Porque, partindo de vós fez-se ouvir a palavra do Senhor, não somente na Macedônia e na Acaia, mas também em todos os lugares a vossa fé para com Deus se divulgou, de tal maneira que não temos necessidade de falar coisa alguma;1Ts 1:9
porque eles mesmos anunciam de nós qual a entrada que tivemos entre vós, e como vos convertestes dos ídolos a Deus, para servirdes ao Deus vivo e verdadeiro,1Ts 1:10
e esperardes dos céus a seu Filho, a quem ele ressuscitou dentre os mortos, a saber, Jesus, que nos livra da ira vindoura.Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#