
// FractionTests.java
// Andrew Davison, ad@coe.psu.ac.th, April 2023

/* Tests of Apache Commons Number's Fraction and BigFraction

   Usage:
     > compile FractionTests.java
     > run FractionTests

   Fraction API:
     https://commons.apache.org/proper/commons-numbers/commons-numbers-docs/apidocs/org/apache/commons/numbers/fraction/Fraction.html
   
   BigFraction API:
     https://commons.apache.org/proper/commons-numbers/commons-numbers-docs/apidocs/org/apache/commons/numbers/fraction/BigFraction.html

   Also see the relevant section in Numbers' User Guide:
   https://commons.apache.org/proper/commons-numbers/userguide/index.html#Fraction

   An alternative to BigFraction is JML's BigRational
*/

import org.apache.commons.numbers.fraction.*;


public class FractionTests
{

  public static void main(String[] args)
  {
    operations();
    extractions();
    comparisons();
    conversions();

    testBigFraction();
  } /* main */


  public static void operations()
  {
    System.out.println("OPERATIONS");

    Fraction fa = Fraction.of(4, 5);
    System.out.println("fa = " + fa);

    Fraction fb = Fraction.of(6, 5);
    System.out.println("fb = " + fb);

    Fraction AaddB = fa.add(fb);
    System.out.println("fa + fb = " + AaddB);

    Fraction AminusB = fa.subtract(fb);
    System.out.println("fa - fb = " + AminusB);

    Fraction AxB=fa.multiply(fb);
    System.out.println("fa * fb = " + AxB);

    Fraction AdivB = fa.divide(fb);
    System.out.println("fa / fb = " + AdivB);

    System.out.println("fa.negate() = " + fa.negate());

    System.out.println("fa.negate().abs() = " + fa.negate().abs());

    System.out.println("fa.reciprocal() = " + fa.reciprocal());
  } /* operations */


  public static void extractions()
  {
    System.out.println("\nEXTRACTIONS");

    Fraction fa = Fraction.of(4,5);
    System.out.println("fa = " + fa);

    System.out.println("getDenominator() = " + fa.getDenominator());

    System.out.println("getNumerator() = " +  fa.getNumerator());

    System.out.println("toString(): \"" + fa.toString() + "\"");
  } /* extractions */


  public static void comparisons()
  {
    System.out.println("\nCOMPARISONS");

    Fraction fa = Fraction.of(4,5);
    Fraction fb = Fraction.of(6,5);

    System.out.println("fa = " + fa);
    System.out.println("fb = " + fb);

    int res = fa.compareTo(fb);
    System.out.println("fa.compareTo(fb): " + res);

    boolean boolres = fa.equals(fb);
    System.out.println("fa.equals(fb): " + boolres);
  } /* comparisons */


  public static void conversions()
  {
    System.out.println("\nCONVERSIONS");

    System.out.println("Reduced Fraction.of(20, 30) = " + Fraction.of(20, 30));

    Fraction fa = Fraction.of(1,239);
    System.out.println("fa = " + fa);

    double fraAdouble = fa.doubleValue();
    System.out.println("fa.doubleValue() = " + fraAdouble);

    float fraAfloat = fa.floatValue();
    System.out.println("fa.floatValue() = " + fraAfloat);

    float fraAint = fa.intValue();
    System.out.println("fa.intValue() = " + fraAint);

    Fraction fraDb = Fraction.from(4.44);
    System.out.println("Fraction.from(4.44) = " + fraDb);

    Fraction fraWND = Fraction.from(Math.PI, 1.0E-6, 100);
    System.out.println("6 dp Fraction.from(Math.PI) = " + fraWND); // 355/133
  } /* conversions */



  private static void testBigFraction()
  {
    System.out.println("\nBIG FRACTIONS");

    BigFraction x = BigFraction.of(1, 200000000);
    BigFraction y = BigFraction.of(1, 300000000);
    BigFraction z = x.add(y);
    System.out.println("1/200000000 + 1/300000000 = " + z);

    // 1/6 - -4/-8 = -1/3
    x = BigFraction.of(1, 6);
    y = BigFraction.of(-4, -8);
    z = x.subtract(y);
    System.out.println("1/6 - -4/-8 = " + z);

    x = BigFraction.of(4, 17000000);
    y = BigFraction.of(17000000, 4);
    z = x.multiply(y);
    System.out.println("4/17000000 * 17000000/4 = " + z);

    z = x.divide(y);
    System.out.println("4/17000000 / 17000000/4 = " + z); 

    x = BigFraction.of(3037141, 3247033);
    y = BigFraction.of(3037547, 3246599);
    z = x.multiply(y);
    System.out.println("3037141/3247033 * 3037547/3246599 = " + z);  // 841/961

    z = x.divide(y);
    System.out.println("3037141/3247033 / 3037547/3246599 = " + z);

    x = BigFraction.of(0, 5);
    System.out.println("0/5 == 0? " + (x.add(x).compareTo(x) == 0));  // true
    // / System.out.println(x.reciprocal());   // divide-by-zero
  }  // end of testBigFraction()


}  // end of FractionTests class