Ybadoo - Soluções em Software Livre
Tutoriais
Programação Orientada a Objetos

(Deitel, 2003) Desenvolva uma classe chamada Rational para realizar aritmética com frações. Utilize variáveis do tipo inteiro para representar as variáveis de instância private da classe - o numerator e o denominator. Forneça um método construtor que permita que um objeto dessa classe seja inicializado quando ele for declarado. O construtor deve armazenar a fração na forma reduzida (isto é, a fração 2/4 seria armazenada no objeto como 1 no numerator e 2 no denominator). Forneça um construtor sem argumentos com valores default caso nenhum inicializador seja fornecido. Forneça métodos public para cada um dos itens a seguir:

  1. adição de dois números Rational, o resultado da adição deve ser armazenado na forma reduzida;
  2. subtração de dois números Rational, o resultado da subtração deve ser armazenado na forma reduzida;
  3. multiplicação de dois números Rational, o resultado da multiplicação deve ser armazenado na forma reduzida;
  4. divisão de dois números Rational, o resultado da divisão deve ser armazenado na forma reduzida;
  5. impressão de números Rational na forma a/b, onde a é o numerator e b é o denominator;
  6. impressão de números Rational em formato de ponto flutuante (considere a possibilidade de fornecer facilidades de formatação que permitam que o usuário da classe especifique o número de dígitos de precisão à direita do ponto de fração decimal).

 

Terminal

ybadoo@server:~$ ./application
Implementação na Linguagem de Programação Java Implementação na Linguagem de Programação C++
Diagrama de Classes na Linguagem de Programação Java Rational.java Application.java
Diagrama de Classes
Diagrama de Classes na Linguagem de Programação Java

Arquivo Rational.java

/*************************************************************************
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)  *
 *                  Ybadoo - Solucoes em Software Livre (ybadoo.com.br)  *
 *                                                                       *
 * Permission is granted to copy, distribute and/or modify this document *
 * under the terms of the GNU Free Documentation License, Version 1.3 or *
 * any later version published by the  Free Software Foundation; with no *
 * Invariant Sections,  no Front-Cover Texts, and no Back-Cover Texts. A *
 * A copy of the  license is included in  the section entitled "GNU Free *
 * Documentation License".                                               *
 *                                                                       *
 * Ubuntu 16.10 (GNU/Linux 4.8.0-39-generic)                             *
 * OpenJDK Version "1.8.0_121"                                           *
 * OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)               *
 *************************************************************************/

package com.ybadoo.tutoriais.poo.tutorial02.exercicio31;

import java.text.DecimalFormat;

/**
 * Classe responsavel pela representacao de um numero racional
 */
public class Rational
{
  /**
   * Precisao padrao de casas decimais
   */
  public static final int PRECISION = 10;

  /**
   * Numerador do numero racional
   */
  private int numerator;

  /**
   * Denominador do numero racional
   */
  private int denominator;

  /**
   * Construtor para inicializar o numero racional
   */
  public Rational()
  {
    this(1, 1);
  }

  /**
   * Construtor para inicializar o numerador e o denominador
   * do numero racional
   *
   * @param numerator numerador do numero racional
   * @param denominator denominador do numero racional
   */
  public Rational(int numerator, int denominator)
  {
    reduction(numerator, denominator);
  }

  /**
   * Retornar o numerador do numero racional
   *
   * @return numerador do numero racional
   */
  public int getNumerator()
  {
    return numerator;
  }

  /**
   * Configurar o numerador do numero racional
   *
   * @param numerator numerador do numero racional
   */
  private void setNumerator(int numerator)
  {
    this.numerator = numerator;
  }

  /**
   * Retornar o denominador do numero racional
   *
   * @return denominador do numero racional
   */
  public int getDenominator()
  {
    return denominator;
  }

  /**
   * Configurar o denominador do numero racional
   *
   * @param denominator denominador do numero racional
   */
  private void setDenominator(int denominator)
  {
    if(denominator != 0)
    {
      this.denominator = denominator;
    }
    else
    {
      this.denominator = 1;
    }
  }

  /**
   * Armazenar o numero racional na forma reduzida
   *
   * @param numerator numerador do numero racional
   * @param denominator denominador do numero racional
   */
  private void reduction(int numerator, int denominator)
  {
    int largest;

    int mdc = 1;

    if(numerator > denominator)
    {
      largest = numerator;
    }
    else
    {
      largest = denominator;
    }

    for(int loop = 2; loop <= largest; loop++)
    {
      if((numerator % loop == 0) && (denominator % loop == 0))
      {
        mdc = loop;
      }
    }

    setNumerator(numerator / mdc);

    setDenominator(denominator / mdc);
  }

  /**
   * Retornar um novo objeto Rational cujo valor eh this + other
   *
   * @param other numero racional a ser adicionado
   * @return novo objeto Rational cujo valor eh this + other
   */
  public Rational addition(Rational other)
  {
    int numerator = this.numerator * other.denominator
      + this.denominator * other.numerator;

    int denominator = this.denominator * other.denominator;

    return new Rational(numerator, denominator);
  }

  /**
   * Retornar um novo objeto Rational cujo valor eh this - other
   *
   * @param other numero racional a ser subtraido
   * @return novo objeto Rational cujo valor eh this - other
   */
  public Rational subtraction(Rational other)
  {
    int numerator = this.numerator * other.denominator
      - this.denominator * other.numerator;

    int denominator = this.denominator * other.denominator;

    return new Rational(numerator, denominator);
  }

  /**
   * Retornar um novo objeto Rational cujo valor eh this * other
   *
   * @param other numero racional a ser multiplicado
   * @return novo objeto Rational cujo valor eh this * other
   */
  public Rational multiplication(Rational other)
  {
    int numerator = this.numerator * other.numerator;

    int denominator = this.denominator * other.denominator;

    return new Rational(numerator, denominator);
  }

  /**
   * Retornar um novo objeto Rational cujo valor eh this / other
   *
   * @param other numero racional a ser dividido
   * @return novo objeto Rational cujo valor eh this / other
   */
  public Rational division(Rational other)
  {
    int numerator = this.numerator * other.denominator;

    int denominator = this.denominator * other.numerator;

    return new Rational(numerator, denominator);
  }

  /* (non-Javadoc)
   * @see java.lang.Object#toString()
   */
  @Override
  public String toString()
  {
    return numerator + "/" + denominator;
  }

  /**
   * Apresentar o numero racional como um numero real
   *
   * @return numero racional como um numero real
   */
  public String formatter()
  {
    return formatter(PRECISION);
  }

  /**
   * Apresentar o numero racional como um numero real, com a precisao de
   * casas decimais desejada pelo usuario
   *
   * @param precision precisao de casas decimais
   * @return numero racional como um numero real
   */
  public String formatter(int precision)
  {
    if(precision <= 0)
    {
      precision = PRECISION;
    }

    String pattern = "0.";

    for(int i = 0; i < precision; i++)
    {
      pattern = pattern + "0";
    }

    DecimalFormat myFormatter = new DecimalFormat(pattern);

    return myFormatter.format(1.0 * numerator / denominator);
  }
}

Arquivo Application.java

/*************************************************************************
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)  *
 *                  Ybadoo - Solucoes em Software Livre (ybadoo.com.br)  *
 *                                                                       *
 * Permission is granted to copy, distribute and/or modify this document *
 * under the terms of the GNU Free Documentation License, Version 1.3 or *
 * any later version published by the  Free Software Foundation; with no *
 * Invariant Sections,  no Front-Cover Texts, and no Back-Cover Texts. A *
 * A copy of the  license is included in  the section entitled "GNU Free *
 * Documentation License".                                               *
 *                                                                       *
 * Ubuntu 16.10 (GNU/Linux 4.8.0-39-generic)                             *
 * OpenJDK Version "1.8.0_121"                                           *
 * OpenJDK 64-Bit Server VM (build 25.121-b13, mixed mode)               *
 *************************************************************************/

package com.ybadoo.tutoriais.poo.tutorial02.exercicio31;

import java.util.Scanner;

/**
 * Classe responsavel pela execucao da classe Rational
 */
public class Application
{
  /**
   * Construtor para inicializar a execucao da classe Rational
   */
  private Application()
  {

  }

  /**
   * Metodo principal da linguagem de programacao Java
   *
   * @param args argumentos da linha de comando (nao utilizado)
   */
  public static void main(String[] args)
  {
    Scanner scanner = new Scanner(System.in);

    System.out.println("Forneça o primeiro número racional");

    System.out.print("Valor do numerador: ");

    int numerator = scanner.nextInt();

    System.out.print("Valor do denominador: ");

    int denominator = scanner.nextInt();

    Rational rational1 = new Rational(numerator, denominator);

    System.out.println("Forneça o segundo número racional");

    System.out.print("Valor do numerador: ");

    numerator = scanner.nextInt();

    System.out.print("Valor do denominador: ");

    denominator = scanner.nextInt();

    Rational rational2 = new Rational(numerator, denominator);

    scanner.close();

    Rational rational3 = rational1.addition(rational2);

    Rational rational4 = rational1.subtraction(rational2);

    Rational rational5 = rational1.multiplication(rational2);

    Rational rational6 = rational1.division(rational2);

    System.out.print(rational1 + " + " + rational2 + " = ");
    System.out.println(rational3 + " (" + rational3.formatter(4) + ")");

    System.out.print(rational1 + " - " + rational2 + " = ");
    System.out.println(rational4 + " (" + rational4.formatter(4) + ")");

    System.out.print(rational1 + " * " + rational2 + " = ");
    System.out.println(rational5 + " (" + rational5.formatter(4) + ")");

    System.out.print(rational1 + " / " + rational2 + " = ");
    System.out.println(rational6 + " (" + rational6.formatter(4) + ")");
  }
}
Diagrama de Classes na Linguagem de Programação C++ Rational.hpp Rational.cpp Application.cpp makefile
Diagrama de Classes
Diagrama de Classes na Linguagem de Programação C++

Arquivo Rational.hpp

/*************************************************************************
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)  *
 *                  Ybadoo - Solucoes em Software Livre (ybadoo.com.br)  *
 *                                                                       *
 * Permission is granted to copy, distribute and/or modify this document *
 * under the terms of the GNU Free Documentation License, Version 1.3 or *
 * any later version published by the  Free Software Foundation; with no *
 * Invariant Sections,  no Front-Cover Texts, and no Back-Cover Texts. A *
 * A copy of the  license is included in  the section entitled "GNU Free *
 * Documentation License".                                               *
 *                                                                       *
 * Ubuntu 16.10 (GNU/Linux 4.8.0-39-generic)                             *
 * g++ (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005                           *
 *************************************************************************/

#ifndef RATIONAL_HPP
#define RATIONAL_HPP

#include <string>

/**
 * Classe responsavel pela representacao de um numero racional
 */
class Rational
{
  public:

  /**
   * Precisao padrao de casas decimais
   */
  static const int PRECISION = 10;

  /**
   * Construtor para inicializar o numero racional
   */
  Rational();

  /**
   * Construtor para inicializar o numerador e o denominador
   * do numero racional
   *
   * @param numerator numerador do numero racional
   * @param denominator denominador do numero racional
   */
  Rational(const int numerator, const int denominator);

  /**
   * Retornar o numerador do numero racional
   *
   * @return numerador do numero racional
   */
  int getNumerator() const;

  /**
   * Retornar o denominador do numero racional
   *
   * @return denominador do numero racional
   */
  int getDenominator() const;

  /**
   * Retornar um novo objeto Rational cujo valor eh this + other
   *
   * @param other numero racional a ser adicionado
   * @return novo objeto Rational cujo valor eh this + other
   */
  Rational* addition(const Rational* other) const;

  /**
   * Retornar um novo objeto Rational cujo valor eh this - other
   *
   * @param other numero racional a ser subtraido
   * @return novo objeto Rational cujo valor eh this - other
   */
  Rational* subtraction(const Rational* other) const;

  /**
   * Retornar um novo objeto Rational cujo valor eh this * other
   *
   * @param other numero racional a ser multiplicado
   * @return novo objeto Rational cujo valor eh this * other
   */
  Rational* multiplication(const Rational* other) const;

  /**
   * Retornar um novo objeto Rational cujo valor eh this / other
   *
   * @param other numero racional a ser dividido
   * @return novo objeto Rational cujo valor eh this / other
   */
  Rational* division(const Rational* other) const;

  /*
   * Retornar o objeto Rational como um texto na forma a/b
   *
   * @return objeto Rational como um texto na forma a/b
   */
  std::string toString() const;

  /**
   * Apresentar o numero racional como um numero real
   *
   * @return numero racional como um numero real
   */
  std::string formatter() const;

  /**
   * Apresentar o numero racional como um numero real, com a precisao de
   * casas decimais desejada pelo usuario
   *
   * @param precision precisao de casas decimais
   * @return numero racional como um numero real
   */
  std::string formatter(int precision) const;

  private:

  /**
   * Numerador do numero racional
   */
  int numerator;

  /**
   * Denominador do numero racional
   */
  int denominator;

  /**
   * Configurar o numerador do numero racional
   *
   * @param numerator numerador do numero racional
   */
  void setNumerator(const int numerator);

  /**
   * Configurar o denominador do numero racional
   *
   * @param denominator denominador do numero racional
   */
  void setDenominator(const int denominator);

  /**
   * Armazenar o numero racional na forma reduzida
   *
   * @param numerator numerador do numero racional
   * @param denominator denominador do numero racional
   */
  void reduction(const int numerator, const int denominator);
};

#endif

Arquivo Rational.cpp

/*************************************************************************
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)  *
 *                  Ybadoo - Solucoes em Software Livre (ybadoo.com.br)  *
 *                                                                       *
 * Permission is granted to copy, distribute and/or modify this document *
 * under the terms of the GNU Free Documentation License, Version 1.3 or *
 * any later version published by the  Free Software Foundation; with no *
 * Invariant Sections,  no Front-Cover Texts, and no Back-Cover Texts. A *
 * A copy of the  license is included in  the section entitled "GNU Free *
 * Documentation License".                                               *
 *                                                                       *
 * Ubuntu 16.10 (GNU/Linux 4.8.0-39-generic)                             *
 * g++ (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005                           *
 *************************************************************************/

#include <iomanip>
#include <sstream>

#include "Rational.hpp"

/**
 * Construtor para inicializar o numero racional
 */
Rational::Rational()
{
  reduction(1, 1);
}

/**
 * Construtor para inicializar o numerador e o denominador
 * do numero racional
 *
 * @param numerator numerador do numero racional
 * @param denominator denominador do numero racional
 */
Rational::Rational(const int numerator, const int denominator)
{
  reduction(numerator, denominator);
}

/**
 * Retornar o numerador do numero racional
 *
 * @return numerador do numero racional
 */
int Rational::getNumerator() const
{
  return numerator;
}

/**
 * Configurar o numerador do numero racional
 *
 * @param numerator numerador do numero racional
 */
void Rational::setNumerator(const int numerator)
{
  Rational::numerator = numerator;
}

/**
 * Retornar o denominador do numero racional
 *
 * @return denominador do numero racional
 */
int Rational::getDenominator() const
{
  return denominator;
}

/**
 * Configurar o denominador do numero racional
 *
 * @param denominator denominador do numero racional
 */
void Rational::setDenominator(const int denominator)
{
  if(denominator != 0)
  {
    Rational::denominator = denominator;
  }
  else
  {
    Rational::denominator = 1;
  }
}

/**
 * Armazenar o numero racional na forma reduzida
 *
 * @param numerator numerador do numero racional
 * @param denominator denominador do numero racional
 */
void Rational::reduction(const int numerator, const int denominator)
{
  int largest = 0;

  int mdc = 1;

  if(numerator > denominator)
  {
    largest = numerator;
  }
  else
  {
    largest = denominator;
  }

  for(int loop = 2; loop <= largest; loop++)
  {
    if((numerator % loop == 0) && (denominator % loop == 0))
    {
      mdc = loop;
    }
  }

  setNumerator(numerator / mdc);

  setDenominator(denominator / mdc);
}

/**
 * Retornar um novo objeto Rational cujo valor eh this + other
 *
 * @param other numero racional a ser adicionado
 * @return novo objeto Rational cujo valor eh this + other
 */
Rational* Rational::addition(const Rational* other) const
{
  int numerator = Rational::numerator * other->denominator
    + Rational::denominator * other->numerator;

  int denominator = Rational::denominator * other->denominator;

  return new Rational(numerator, denominator);
}

/**
 * Retornar um novo objeto Rational cujo valor eh this - other
 *
 * @param other numero racional a ser subtraido
 * @return novo objeto Rational cujo valor eh this - other
 */
Rational* Rational::subtraction(const Rational* other) const
{
  int numerator = Rational::numerator * other->denominator
    - Rational::denominator * other->numerator;

  int denominator = Rational::denominator * other->denominator;

  return new Rational(numerator, denominator);
}

/**
 * Retornar um novo objeto Rational cujo valor eh this * other
 *
 * @param other numero racional a ser multiplicado
 * @return novo objeto Rational cujo valor eh this * other
 */
Rational* Rational::multiplication(const Rational* other) const
{
  int numerator = Rational::numerator * other->numerator;

  int denominator = Rational::denominator * other->denominator;

  return new Rational(numerator, denominator);
}

/**
 * Retornar um novo objeto Rational cujo valor eh this / other
 *
 * @param other numero racional a ser dividido
 * @return novo objeto Rational cujo valor eh this / other
 */
Rational* Rational::division(const Rational* other) const
{
  int numerator = Rational::numerator * other->denominator;

  int denominator = Rational::denominator * other->numerator;

  return new Rational(numerator, denominator);
}

/*
 * Retornar o objeto Rational como um texto na forma a/b
 *
 * @return objeto Rational como um texto na forma a/b
 */
std::string Rational::toString() const
{
  using namespace std;

  stringstream buffer;

  buffer << numerator << "/" << denominator;

  return buffer.str();
}

/**
 * Apresentar o numero racional como um numero real
 *
 * @return numero racional como um numero real
 */
std::string Rational::formatter() const
{
  return formatter(PRECISION);
}

/**
 * Apresentar o numero racional como um numero real, com a precisao de
 * casas decimais desejada pelo usuario
 *
 * @param precision precisao de casas decimais
 * @return numero racional como um numero real
 */
std::string Rational::formatter(int precision) const
{
  using namespace std;

  if(precision <= 0)
  {
    precision = PRECISION;
  }

  float result = 1.0 * numerator / denominator;

  stringstream buffer;

  buffer << fixed << setprecision(precision) << result;

  return buffer.str();
}

Arquivo Application.cpp

/*************************************************************************
 * Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)  *
 *                  Ybadoo - Solucoes em Software Livre (ybadoo.com.br)  *
 *                                                                       *
 * Permission is granted to copy, distribute and/or modify this document *
 * under the terms of the GNU Free Documentation License, Version 1.3 or *
 * any later version published by the  Free Software Foundation; with no *
 * Invariant Sections,  no Front-Cover Texts, and no Back-Cover Texts. A *
 * A copy of the  license is included in  the section entitled "GNU Free *
 * Documentation License".                                               *
 *                                                                       *
 * Ubuntu 16.10 (GNU/Linux 4.8.0-39-generic)                             *
 * g++ (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005                           *
 *************************************************************************/

#include <iostream>

#include "Rational.hpp"

/**
 * Metodo principal da linguagem de programacao C++
 *
 * @param argc quantidade de argumentos na linha de comando (nao utilizado)
 * @param argv argumentos da linha de comando (nao utilizado)
 */
int main(int argc, char** argv)
{
  using namespace std;

  int numerator;

  int denominator;

  cout << "Forneça o primeiro número racional" << endl;

  cout << "Valor do numerador: ";
  cin  >> numerator;

  cout << "Valor do denominador: ";
  cin  >> denominator;

  Rational* rational1 = new Rational(numerator, denominator);

  cout << "Forneça o segundo número racional" << endl;

  cout << "Valor do numerador: ";
  cin  >> numerator;

  cout << "Valor do denominador: ";
  cin  >> denominator;

  Rational* rational2 = new Rational(numerator, denominator);

  Rational* rational3 = rational1->addition(rational2);

  Rational* rational4 = rational1->subtraction(rational2);

  Rational* rational5 = rational1->multiplication(rational2);

  Rational* rational6 = rational1->division(rational2);

  cout << rational1->toString() << " + " << rational2->toString() << " = "
       << rational3->toString() << " (" << rational3->formatter(4) << ")"
       << endl;

  cout << rational1->toString() << " - " << rational2->toString() << " = "
       << rational4->toString() << " (" << rational4->formatter(4) << ")"
       << endl;

  cout << rational1->toString() << " * " << rational2->toString() << " = "
       << rational5->toString() << " (" << rational5->formatter(4) << ")"
       << endl;

  cout << rational1->toString() << " / " << rational2->toString() << " = "
       << rational6->toString() << " (" << rational6->formatter(4) << ")"
       << endl;

  delete rational1;

  delete rational2;

  delete rational3;

  delete rational4;

  delete rational5;

  delete rational6;

  return 0;
}

Arquivo makefile

##########################################################################
 # Copyright (C) 2009/2024 - Cristiano Lehrer (cristiano@ybadoo.com.br)  #
 #                  Ybadoo - Solucoes em Software Livre (ybadoo.com.br)  #
 #                                                                       #
 # Permission is granted to copy, distribute and/or modify this document #
 # under the terms of the GNU Free Documentation License, Version 1.3 or #
 # any later version published by the  Free Software Foundation; with no #
 # Invariant Sections,  no Front-Cover Texts, and no Back-Cover Texts. A #
 # A copy of the  license is included in  the section entitled "GNU Free #
 # Documentation License".                                               #
 #                                                                       #
 # Ubuntu 16.10 (GNU/Linux 4.8.0-39-generic)                             #
 # gcc/g++ (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005                       #
 ##########################################################################

g++ -o Rational.o -c Rational.cpp

g++ -o Application.o -c Application.cpp

g++ -o application Rational.o Application.o

Deitel, H. M. (2003). Java, como programar. 4ª edição. Porto Alegre: Bookman. 1.386 páginas.