Java Training Course/JT07: Difference between revisions

From tehowiki
Jump to navigation Jump to search
imported>Gfis
Created page with "==Class ''Rational''== We now leave the conventional programming style of C (and Pascal, BASIC, FORTRAN etc.), and we enter the field of real object-oriented programming. We r..."
 
imported>Gfis
Program Skeleton
 
Line 23: Line 23:
     public Rational subtract(Rational rat2) { ... }
     public Rational subtract(Rational rat2) { ... }
     public String toString() { ... }
     public String toString() { ... }
===Starting Code===
===Program Skeleton===
/* Fractions of integers
<pre>
  * @(#) $Id$
/* Rational - Exact Fractions of Integers
  * 2017-09-23, Georg Fischer
* @(#) $Id$
  */
* 2017-09-23, Georg Fischer
// package name will later go here
*/
// imports will later go here
// package declaration goes here (later)
   
import java.io.Serializable; // we have a 'toString' method
/** Class <wm>Rational</em> represents an integer fraction
import java.lang.Cloneable; // we have a 'clone' method
  *  together with the arithmetic operations on such Rationals.
import java.lang.Integer; // parseInt
  *  The denominator is always > 0. All arithmetic operations
import java.lang.Math;    // abs
  * return reduced fractions where GCD(numerator, denominator) = 1.
import java.lang.String; // substring, indexOf, valueOf
  * The methods have name, parameters and return values analogous to methods
import java.lang.System;  // out.println()
  of the Java object type BigInteger, see
 
  https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html
/** Class <em>Rational</em> represents an integer fraction
  */
together with the arithmetic operations on such Rationals.
  public class Rational {
The denominator is always > 0. All arithmetic operations
    //----------------
return reduced fractions where GCD(numerator, denominator) = 1.
    // Internal Properties
*  The methods have name, parameters and return values analogous to methods
    //----------------
*  of the Java object type BigInteger, see
    /** value above the bar, before the slash */
*  https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html
    private int numerator;
  */
    /** value below the bar, after the slash */
public class Rational implements Cloneable, Serializable {
    private int denominator;
    //----------------
    // Internal Properties
    //----------------
    //----------------
    // Constructors
    /** value above the bar, before the slash */
    //----------------
    private int numerator;
    /** No-args constructor, creates 1/1
    /** value below the bar, after  the slash */
      */
    private int denominator;
    public Rational() {
 
        numerator   = 1;
    //----------------
        denominator = 1;
    // Constructors
    } // no-args constructor
    //----------------
    /** No-args constructor, creates 1/1
    /** Constructor with numerator, creates a/1
    */
      * @param a numerator
    public Rational() {
      */
        numerator  = 1;
    public Rational(int a) {
        denominator = 1;
        numerator  = a;
    } // no-args constructor
        denominator = 1;
 
    } // constructor(int)
    /** Constructor with numerator, creates a/1
    *  @param a numerator
    /** Constructor with numerator and denominator, creates a/b
    */
      *  @param a numerator
    public Rational(int a) {
      *  @param b denominator
        numerator  = a;
      */
        denominator = 1;
    public Rational(int a, int b) {
    } // constructor(int)
        numerator  = a;
 
        denominator = b;
    /** Constructor with numerator and denominator, creates a/b.
    } // constructor(int, int)
    Also reduces and normalizes the fraction, that means:
    * <ul>
    /** Constructor from a String representation, creates a/b
     *  <li>divides the numerator and the denominator by
      @param str String of the form "a/b"
    *  their greatest common divisor, if that is &gt; 1,</li>
      */
    *  <li>makes the denominator always positive,</li>
     public Rational(String str) {
    *  <li>normalizes the denominator to 1 if the numerator is 0.</li>
        int slashPos = str.indexOf("/");
     *  </ul>
        if (slashPos < 0) {
    *  @param a numerator
            str += "/1";
    * @param b denominator
            slashPos = str.length() - 2;
     */
        }
    public Rational(int a, int b) {
        numerator   = Integer.parseInt(str.substring(0, slashPos));
        numerator  = a;
        denominator = Integer.parseInt(str.substring(slashPos + 1));
        denominator = b;
     } // constructor(String)
        int common = gcd(numerator, denominator);
   
        if (common > 1) {
     //----------------
            numerator  /= common;
    // Internal getters
            denominator /= common;
    //----------------
        }
    /** Gets the numerator
        if (numerator == 0) {
      *  @return the numerator  of <em>this</em> Rational
            denominator = 1;
      */
        } else if (denominator < 0) {
    private int getNum() {
            numerator  = - numerator;
        return numerator;
            denominator = - denominator;
    } // getNum()
        }
    } // constructor(int, int)
    /** Gets the denominator
 
      *  @return the denominator of <em>this</em> Rational
    /** Constructor from a String representation, creates a/b
      */
    *  @param str String of the form "a/b"
    private int getDen() {
    */
        return denominator;
    public Rational(String str) {
    } // getDen()
        int slashPos = str.indexOf("/");
        if (slashPos < 0) {
    //----------------
            str += "/1";
    // Public methods
            slashPos = str.length() - 2;
    //----------------
        }
    /** Returns the greatest common divisor of 2 integers.
        numerator    = Integer.parseInt(str.substring(0, slashPos));
      *  @param a 1st integer
        denominator  = Integer.parseInt(str.substring(slashPos + 1));
      *  @param b 2nd integer
        Rational rat = new Rational(numerator, denominator); // this will reduce and normalize
      *  @return gcd(a,b), which is always positive
        numerator    = rat.getNum();
      */
        denominator  = rat.getDen();
    public static int gcd(int a, int b) {
    } // constructor(String)
        int result = 0;
 
        // not yet implemented
    public Rational clone() {
        return result;
        return new Rational(this.numerator, this.denominator);
    } // gcd(int,int)
    } // clone
 
    /** Returns the least common multiple of 2 integers.
    //----------------
      *  @param a 1st integer
    // Internal getters for the properties of the class
      *  @param b 2nd integer
    //----------------
      *  @return lcm(a,b)
    /** Gets the numerator
      */
    @return the numerator   of <em>this</em> Rational
    public static int lcm(int a, int b) {
    */
        int result = a * b;
    private int getNum() {
        if (result < 0) { // absolute, make positive
        return numerator;
            result = - result;
    } // getNum()
        } // abs
 
        return result / gcd(a, b);
    /** Gets the denominator
    } // lcm(int,int)
    @return the denominator of <em>this</em> Rational
    */
    /** Reduces and normalizes the fraction, that means:
    private int getDen() {
      &lt;ul&gt;
        return denominator;
      *  &lt;li&gt;divides the numerator and the denominator by
    } // getDen()
      * their greatest common divisor, if that is &gt; 1,&lt;/li&gt;
 
      *  &lt;li&gt;makes the denominator always positive,&lt;/li&gt;
    //----------------
      &lt;li&gt;normalizes the denominator to 1 if the numerator is 0.&lt;/li&gt;
    // Public methods
      * &lt;/ul&gt;
    //----------------
      */
</pre>
    public Rational reduce() {
Code for desired methods goes here
        int common = gcd(numerator, denominator);
<pre>
        if (common > 1) {
    //================
            numerator  /= common;
    /** Test program, shows a series of fixed operations
            denominator /= common;
    *  @param args String array of commandline arguments
        }
    */
        if (numerator == 0) {
    public static void main(String[] args) {
            denominator = 1;
        int iarg = 1;
        } else if (denominator < 0) {
        String  str0 = "0/1";
            numerator  = - numerator;
        Rational rat0 = new Rational(str0);
            denominator = - denominator;
        while (iarg < args.length) {
        }
            String   str1 = args[iarg];
        return this;
            Rational rat1 = new Rational(str1);
    } // reduce()
            System.out.println(               str0 + " + " + str1 +  " = " + rat0.add      (rat1).toString());
 
            System.out.println(              str0 + " - " + str1 +  " = " + rat0.subtract (rat1).toString());
    /** Returns the difference between <em>this</em> Rational and a second.
            System.out.println(              str0 + " * " + str1 + " = " + rat0.multiply (rat1).toString());
      *  @param rat2 2nd Rational
            System.out.println(              str0 + " / " + str1 +  " = " + rat0.divide  (rat1).toString());
      *  @return (this - rat2)
            System.out.println("max("      + str0 + ", "  + str1 + ") = " + rat0.max      (rat1).toString());
      */
            System.out.println("min("      + str0 + ", " + str1 + ") = " + rat0.min      (rat1).toString());
    public Rational subtract(Rational rat2) {
            System.out.println("isInteger(" + str0                + ") = " + rat0.isInteger()               );
        return this.add(rat2.negate());
            System.out.println("intValue (" + str0                + ") = " + rat0.intValue ()               );
    } // subtract(Rational)
            System.out.println();
            str0 = str1;
    /** Returns <em>this</em> Rational as a String.
            rat0 = rat1;
      *  @return a String of the form "a/b", or only "a" if b is 1.
            iarg ++;
      */
        } // while iarg
    public String toString() {
    } // main
        String result = String.valueOf(numerator);
 
        if (denominator != 1) {
} // Rational
            result += "/" + String.valueOf(denominator);
</pre>
        }
        return result;
    } // toString()
    //================
    /** Test program, shows a series of fixed operations
      @param args String array of commandline arguments
      */
    public static void main(String[] args) {
        int iarg = 1;
        String  str0 = "0/1";
        Rational rat0 = new Rational(str0);
        while (iarg < args.length) {
            String  str1 = args[iarg];
            Rational rat1 = new Rational(str1);
            System.out.println(str0 + " + " + str1 + " = " + rat0.add    (rat1).toString());
            System.out.println(str0 + " - " + str1 + " = " + rat0.subtract(rat1).toString());
            System.out.println(str0 + " * " + str1 + " = " + rat0.multiply(rat1).toString());
            System.out.println(str0 + " / " + str1 + " = " + rat0.divide  (rat1).toString());
            str0 = str1;
            rat0 = rat1;
            iarg ++;
        } // while iarg
    } // main
} // Rational
[[Java Training Course/JT05|&lt; Previous: JT06]] Preliminary Class ''Ratio''<br />
[[Java Training Course/JT05|&lt; Previous: JT06]] Preliminary Class ''Ratio''<br />
[[Java Training Course/JT07|&gt; Next: JT08]] Discussion
[[Java Training Course/JT07|&gt; Next: JT08]] Discussion

Latest revision as of 20:17, 26 September 2017

Class Rational

We now leave the conventional programming style of C (and Pascal, BASIC, FORTRAN etc.), and we enter the field of real object-oriented programming. We rewrite the class Ratio from JT06, and we remove the static qualifier from most methods. In the new class Rational the first (implied) parameter is the current object thisin most cases. Instead of:

   public static Ratio subtract(Ratio rat1, Ratio rat2) {
       return add(rat1, negate(rat2));
   } // subtract(Ratio, Ratio)

we write:

   public Rational subtract(Rational rat2) {
       return this.add(rat2.negate());
   } // subtract(Rational)

Desired Methods

Besides the 4 basic arithmetic operations we want to implement some more useful methods. In this session, the following list should be expanded with proper documentation comments and method bodies:

    public Rational abs() { ... }
    public Rational add(Rational rat2) { ... }
    public int compareTo(Rational rat2) { ... }
    public Rational divide(Rational rat2) { ... }
    public boolean equals(Rational rat2) { ... }
    public boolean isInteger() { return denominator == 1; }
    public int intValue() { return numerator / denominator; }
    public Rational max(Rational rat2) { return this.compareTo(rat2) > 0 ? this : rat2 }
    public Rational min(Rational rat2) { return this.compareTo(rat2) < 0 ? this : rat2 }
    public Rational multiply(Rational rat2) { ... }
    public Rational negate() { return new Rational(- numerator, denominator); }
    public Rational subtract(Rational rat2) { ... }
    public String toString() { ... }

Program Skeleton

/* Rational - Exact Fractions of Integers
 * @(#) $Id$
 * 2017-09-23, Georg Fischer
 */
// package declaration goes here (later)
import java.io.Serializable; // we have a 'toString' method
import java.lang.Cloneable;  // we have a 'clone' method
import java.lang.Integer; // parseInt
import java.lang.Math;    // abs
import java.lang.String;  // substring, indexOf, valueOf
import java.lang.System;  // out.println()

/** Class <em>Rational</em> represents an integer fraction
 *  together with the arithmetic operations on such Rationals.
 *  The denominator is always > 0. All arithmetic operations
 *  return reduced fractions where GCD(numerator, denominator) = 1.
 *  The methods have name, parameters and return values analogous to methods
 *  of the Java object type BigInteger, see
 *  https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html
 */
public class Rational implements Cloneable, Serializable {
    //----------------
    // Internal Properties
    //----------------
    /** value above the bar, before the slash */
    private int numerator;
    /** value below the bar, after  the slash */
    private int denominator;

    //----------------
    // Constructors
    //----------------
    /** No-args constructor, creates 1/1
     */
    public Rational() {
        numerator   = 1;
        denominator = 1;
    } // no-args constructor

    /** Constructor with numerator, creates a/1
     *  @param a numerator
     */
    public Rational(int a) {
        numerator   = a;
        denominator = 1;
    } // constructor(int)

    /** Constructor with numerator and denominator, creates a/b.
     *  Also reduces and normalizes the fraction, that means:
     *  <ul>
     *  <li>divides the numerator and the denominator by
     *  their greatest common divisor, if that is > 1,</li>
     *  <li>makes the denominator always positive,</li>
     *  <li>normalizes the denominator to 1 if the numerator is 0.</li>
     *  </ul>
     *  @param a numerator
     *  @param b denominator
     */
    public Rational(int a, int b) {
        numerator   = a;
        denominator = b;
        int common = gcd(numerator, denominator);
        if (common > 1) {
            numerator   /= common;
            denominator /= common;
        }
        if (numerator == 0) {
            denominator = 1;
        } else if (denominator < 0) {
            numerator   = - numerator;
            denominator = - denominator;
        }
    } // constructor(int, int)

    /** Constructor from a String representation, creates a/b
     *  @param str String of the form "a/b"
     */
    public Rational(String str) {
        int slashPos = str.indexOf("/");
        if (slashPos < 0) {
            str += "/1";
            slashPos = str.length() - 2;
        }
        numerator    = Integer.parseInt(str.substring(0, slashPos));
        denominator  = Integer.parseInt(str.substring(slashPos + 1));
        Rational rat = new Rational(numerator, denominator); // this will reduce and normalize
        numerator    = rat.getNum();
        denominator  = rat.getDen();
    } // constructor(String)

    public Rational clone() {
        return new Rational(this.numerator, this.denominator);
    } // clone

    //----------------
    // Internal getters for the properties of the class
    //----------------
    /** Gets the numerator
     *  @return the numerator   of <em>this</em> Rational
     */
    private int getNum() {
        return numerator;
    } // getNum()

    /** Gets the denominator
     *  @return the denominator of <em>this</em> Rational
     */
    private int getDen() {
        return denominator;
    } // getDen()

    //----------------
    // Public methods
    //----------------

Code for desired methods goes here

    //================
    /** Test program, shows a series of fixed operations
     *  @param args String array of commandline arguments
     */
    public static void main(String[] args) {
        int iarg = 1;
        String   str0 = "0/1";
        Rational rat0 = new Rational(str0);
        while (iarg < args.length) {
            String   str1 = args[iarg];
            Rational rat1 = new Rational(str1);
            System.out.println(               str0 + " + " + str1 +  " = " + rat0.add      (rat1).toString());
            System.out.println(               str0 + " - " + str1 +  " = " + rat0.subtract (rat1).toString());
            System.out.println(               str0 + " * " + str1 +  " = " + rat0.multiply (rat1).toString());
            System.out.println(               str0 + " / " + str1 +  " = " + rat0.divide   (rat1).toString());
            System.out.println("max("       + str0 + ", "  + str1 + ") = " + rat0.max      (rat1).toString());
            System.out.println("min("       + str0 + ", "  + str1 + ") = " + rat0.min      (rat1).toString());
            System.out.println("isInteger(" + str0                + ") = " + rat0.isInteger()               );
            System.out.println("intValue (" + str0                + ") = " + rat0.intValue ()               );
            System.out.println();
            str0 = str1;
            rat0 = rat1;
            iarg ++;
        } // while iarg
    } // main

} // Rational

< Previous: JT06 Preliminary Class Ratio
> Next: JT08 Discussion