Modeled after BigInteger/BigDecimal. Instances of this class are immutable, and simplified upon construction. The returned numerator() and denominator() are never negative; the sign can be retrieved via signum(). The denominator for zero is always 1 (e.g. 0/5 is simplified to 0/1), and signed zeros are not supported (e.g. 0/-1 is simplified to 0/1).

import java.math.BigDecimal ;

import java.math.BigInteger ;

import java.math.RoundingMode ;



public class BigRational extends Number implements Comparable < BigRational >

{



public final static BigRational ZERO = new BigRational ( false , BigInteger . ZERO , BigInteger . ONE ) ;

public final static BigRational ONE = new BigRational ( false , BigInteger . ONE , BigInteger . ONE ) ;



private final boolean isNegative ;

private final BigInteger numerator ;

private final BigInteger denominator ;

private final int hashCode ;



private BigRational ( boolean isNegative, BigInteger nonNegativeNumerator, BigInteger nonNegativeDenominator )

{

this . isNegative = isNegative ;

this . numerator = nonNegativeNumerator ;

this . denominator = nonNegativeDenominator ;

this . hashCode = computeHashCode ( isNegative, nonNegativeNumerator, nonNegativeDenominator ) ;

}



private BigRational ( BigInteger numerator, BigInteger denominator, boolean ignoreComponentSigns, boolean forcedSign )

{

if ( denominator. equals ( BigInteger . ZERO ) )

throw new ArithmeticException ( "Denominator is zero" ) ;

boolean isNegative = ignoreComponentSigns ? forcedSign : false ;

if ( numerator. equals ( BigInteger . ZERO ) )

{

denominator = BigInteger . ONE ;

isNegative = false ;

}

else

{

if ( numerator. signum ( ) < 0 )

{

if ( ! ignoreComponentSigns )

isNegative = true ;

numerator = numerator. negate ( ) ;

}

if ( denominator. signum ( ) < 0 )

{

if ( ! ignoreComponentSigns )

isNegative = ! isNegative ;

denominator = denominator. negate ( ) ;

}

BigInteger gcd = numerator. gcd ( denominator ) ;

if ( ! gcd. equals ( BigInteger . ONE ) )

{

numerator = numerator. divide ( gcd ) ;

denominator = denominator. divide ( gcd ) ;

}

}

this . isNegative = isNegative ;

this . numerator = numerator ;

this . denominator = denominator ;

this . hashCode = computeHashCode ( isNegative, numerator, denominator ) ;

}



public BigRational ( BigInteger numerator, BigInteger denominator )

{ this ( numerator, denominator, false , false ) ; }



public BigRational abs ( )

{ return isNegative ? new BigRational ( false , numerator, denominator ) : this ; }



public BigRational add ( BigRational br )

{

if ( isNegative == br. isNegative )

return addIgnoreNegatives ( isNegative, this , br ) ;

if ( isNegative )

return subtractIgnoreNegatives ( br, this ) ;

return subtractIgnoreNegatives ( this , br ) ;

}



public int compareTo ( BigRational br )

{

if ( isNegative != br. isNegative )

return isNegative ? - 1 : 1 ;

return subtract ( br ) . signum ( ) ;

}



public BigRational decrement ( )

{

if ( isNegative )

return new BigRational ( numerator. add ( denominator ) , denominator, true , true ) ;

return new BigRational ( numerator. subtract ( denominator ) , denominator, true , ( numerator. compareTo ( denominator ) < 0 ) ) ;

}



public BigInteger denominator ( )

{ return denominator ; }



public BigRational divide ( BigInteger bi )

{

boolean isNegative = ( bi. signum ( ) < 0 ) ;

if ( isNegative )

bi = bi. negate ( ) ;

isNegative = ( isNegative != this . isNegative ) ;

return new BigRational ( numerator, denominator. multiply ( bi ) , true , isNegative ) ;

}



public BigRational divide ( BigRational divisor )

{ return multiply ( divisor. reciprocal ( ) ) ; }



public double doubleValue ( )

{ return toBigDecimal ( 18 , RoundingMode. HALF_EVEN ) . doubleValue ( ) ; }



public boolean equals ( Object o )

{

if ( ( o == null ) || ! ( o instanceof BigRational ) )

return false ;

BigRational br = ( BigRational ) o ;

return ( isNegative == br. isNegative ) && numerator. equals ( br. numerator ) && denominator. equals ( br. denominator ) ;

}



public float floatValue ( )

{ return toBigDecimal ( 9 , RoundingMode. HALF_EVEN ) . floatValue ( ) ; }



public int hashCode ( )

{ return hashCode ; }



public BigRational increment ( )

{

if ( ! isNegative )

return new BigRational ( numerator. add ( denominator ) , denominator, true , false ) ;

return new BigRational ( numerator. subtract ( denominator ) , denominator, true , ( numerator. compareTo ( denominator ) > 0 ) ) ;

}



public int intValue ( )

{ return toBigDecimal ( 12 , RoundingMode. HALF_EVEN ) . intValue ( ) ; }



public boolean isWholeNumber ( )

{ return denominator. equals ( BigInteger . ONE ) ; }



public boolean isZero ( )

{ return numerator. equals ( BigInteger . ZERO ) ; }



public long longValue ( )

{ return toBigDecimal ( 21 , RoundingMode. HALF_EVEN ) . longValue ( ) ; }



public BigRational max ( BigRational br )

{ return ( compareTo ( br ) >= 0 ) ? this : br ; }



public BigRational min ( BigRational br )

{ return ( compareTo ( br ) <= 0 ) ? this : br ; }



public Object [ ] mixedFraction ( )

{

BigInteger [ ] dar = numerator. divideAndRemainder ( denominator ) ;

BigInteger whole = dar [ 0 ] ;

if ( isNegative )

whole = whole. negate ( ) ;

BigRational fraction = new BigRational ( dar [ 1 ] , denominator, true , isNegative ) ;

return new Object [ ] { whole, fraction } ;

}



public BigRational multiply ( BigInteger bi )

{

boolean isNegative = ( bi. signum ( ) < 0 ) ;

if ( isNegative )

bi = bi. negate ( ) ;

isNegative = ( isNegative != this . isNegative ) ;

return new BigRational ( numerator. multiply ( bi ) , denominator, true , isNegative ) ;

}



public BigRational multiply ( BigRational br )

{

BigInteger numerator = this . numerator . multiply ( br. numerator ) ;

BigInteger denominator = this . denominator . multiply ( br. denominator ) ;

return new BigRational ( numerator, denominator, true , isNegative != br. isNegative ) ;

}



public BigRational negate ( )

{

if ( isZero ( ) )

return this ;

return new BigRational ( ! isNegative, numerator, denominator ) ;

}



public BigInteger numerator ( )

{ return numerator ; }



public BigRational pow ( int n )

{

BigInteger numerator = this . numerator . pow ( n ) ;

BigInteger denominator = this . denominator . pow ( n ) ;

return new BigRational ( numerator, denominator, true , isNegative ? ( ( n & 1 ) != 0 ) : false ) ;

}



public BigRational reciprocal ( )

{

if ( isZero ( ) )

throw new ArithmeticException ( "Can not calculate reciprocal of zero" ) ;

return new BigRational ( isNegative, denominator, numerator ) ;

}



public int signum ( )

{

if ( isZero ( ) )

return 0 ;

return isNegative ? - 1 : 1 ;

}



public BigRational subtract ( BigRational br )

{

if ( isNegative != br. isNegative )

return addIgnoreNegatives ( isNegative, this , br ) ;

if ( isNegative )

return subtractIgnoreNegatives ( br, this ) ;

return subtractIgnoreNegatives ( this , br ) ;

}



public BigDecimal toBigDecimal ( int desiredPrecision, RoundingMode roundingMode )

{

BigDecimal bdNumerator = new BigDecimal ( numerator ) ;

BigDecimal bdDenominator = new BigDecimal ( denominator ) ;

int resultScale = bdNumerator. scale ( ) - bdDenominator. scale ( ) - bdNumerator. precision ( ) + bdDenominator. precision ( ) + desiredPrecision ;

BigDecimal bigDecimalValue = bdNumerator. divide ( bdDenominator, resultScale, roundingMode ) ;

if ( bigDecimalValue. precision ( ) > desiredPrecision )

bigDecimalValue = bigDecimalValue. setScale ( bigDecimalValue. scale ( ) - 1 , roundingMode ) ;

if ( isNegative )

bigDecimalValue = bigDecimalValue. negate ( ) ;

return bigDecimalValue ;

}



public BigDecimal toBigDecimalExact ( )

{

BigDecimal bigDecimalValue = new BigDecimal ( numerator ) . divide ( new BigDecimal ( denominator ) ) ;

if ( isNegative )

bigDecimalValue = bigDecimalValue. negate ( ) ;

return bigDecimalValue ;

}



public String toString ( )

{

if ( isWholeNumber ( ) )

{

if ( isNegative )

return "-" + numerator. toString ( ) ;

return numerator. toString ( ) ;

}

if ( isNegative )

return "-" + numerator. toString ( ) + "/" + denominator. toString ( ) ;

return numerator. toString ( ) + "/" + denominator. toString ( ) ;

}



private static int computeHashCode ( boolean isNegative, BigInteger numerator, BigInteger denominator )

{

int c = numerator. hashCode ( ) + denominator. hashCode ( ) ;

if ( isNegative )

c = ~c ;

return c ;

}



private static BigRational addIgnoreNegatives ( boolean resultIsNegative, BigRational first, BigRational second )

{

first = first. abs ( ) ;

second = second. abs ( ) ;

BigInteger numerator = null ;

BigInteger denominator = null ;

if ( first. denominator . equals ( second. denominator ) )

{

numerator = first. numerator . add ( second. numerator ) ;

denominator = first. denominator ;

}

else

{

numerator = first. numerator . multiply ( second. denominator ) . add ( second. numerator . multiply ( first. denominator ) ) ;

denominator = first. denominator . multiply ( second. denominator ) ;

}

return new BigRational ( numerator, denominator, true , resultIsNegative ) ;

}



private static BigRational subtractIgnoreNegatives ( BigRational first, BigRational second )

{

first = first. abs ( ) ;

second = second. abs ( ) ;

BigInteger numerator = null ;

BigInteger denominator = null ;

if ( first. denominator . equals ( second. denominator ) )

{

numerator = first. numerator . subtract ( second. numerator ) ;

denominator = first. denominator ;

}

else

{

numerator = first. numerator . multiply ( second. denominator ) . subtract ( second. numerator . multiply ( first. denominator ) ) ;

denominator = first. denominator . multiply ( second. denominator ) ;

}

return new BigRational ( numerator, denominator ) ;

}



public static BigRational valueOf ( int integerValue )

{ return valueOf ( integerValue, 1 ) ; }



public static BigRational valueOf ( int numerator, int denominator )

{ return new BigRational ( BigInteger . valueOf ( numerator ) , BigInteger . valueOf ( denominator ) ) ; }



public static BigRational valueOf ( long longValue )

{ return valueOf ( longValue, 1 ) ; }



public static BigRational valueOf ( long numerator, long denominator )

{ return new BigRational ( BigInteger . valueOf ( numerator ) , BigInteger . valueOf ( denominator ) ) ; }



public static BigRational valueOf ( BigDecimal bigDecimalValue )

{

int scale = bigDecimalValue. scale ( ) ;

BigInteger numerator = bigDecimalValue. unscaledValue ( ) ;

if ( scale <= 0 )

{

if ( scale < 0 )

numerator = numerator. multiply ( BigInteger . TEN . pow ( - scale ) ) ;

return new BigRational ( numerator, BigInteger . ONE ) ;

}

return new BigRational ( numerator, BigInteger . TEN . pow ( scale ) ) ;

}



public static BigRational valueOf ( BigDecimal numerator, BigDecimal denominator )

{ return valueOf ( numerator ) . divide ( valueOf ( denominator ) ) ; }



public static BigRational valueOf ( double doubleValue )

{ return valueOf ( new BigDecimal ( doubleValue ) ) ; }



public static BigRational valueOf ( double numerator, double denominator )

{ return valueOf ( numerator ) . divide ( valueOf ( denominator ) ) ; }



public static BigRational valueOf ( String number )

{

int slashIndex = number. indexOf ( "/" ) ;

if ( slashIndex > 0 )

return valueOf ( number. substring ( 0 , slashIndex ) , number. substring ( slashIndex + 1 ) ) ;

return valueOf ( new BigDecimal ( number ) ) ;

}



public static BigRational valueOf ( String numerator, String denominator )

{ return valueOf ( numerator ) . divide ( valueOf ( denominator ) ) ; }



/* ******************** Testing ******************** */



public static boolean testEquals ( String testName, Object obj, String str )

{ return testEquals ( testName, obj, null , str ) ; }



public static boolean testEquals ( String testName, Object obj1, Object obj2, String str )

{

// obj2 is optional

boolean objEquality = ( obj2 == null ) || obj1. equals ( obj2 ) ;

String objStr = ( obj1 instanceof BigDecimal ) ? ( ( BigDecimal ) obj1 ) . toPlainString ( ) : obj1. toString ( ) ;

boolean strEquality = objStr. equals ( str ) ;

if ( objEquality && strEquality )

{

System . out . println ( "PASS: " + testName ) ;

return true ;

}

String err = "FAIL: " + testName + ": " + obj1. toString ( ) + " not equal to" ;

if ( ! objEquality )

err += " object " + obj2. toString ( ) ;

if ( ! strEquality )

{

if ( ! objEquality )

err += " and" ;

err += " string " + str ;

}

System . out . println ( err ) ;

return false ;

}



public static boolean testTrue ( String testName, boolean b )

{

System . out . println ( ( b ? "PASS: " : "FAIL: " ) + testName ) ;

return b ;

}



public static boolean testFeatures ( )

{

boolean passedAll = true ;

passedAll &= testEquals ( "BaseConstructor-1" , new BigRational ( BigInteger . valueOf ( 30 ) , BigInteger . valueOf ( 72 ) ) , new BigRational ( BigInteger . valueOf ( 5 ) , BigInteger . valueOf ( 12 ) ) , "5/12" ) ;

passedAll &= testEquals ( "BaseConstructor-2" , new BigRational ( BigInteger . valueOf ( - 30 ) , BigInteger . valueOf ( 72 ) ) , new BigRational ( BigInteger . valueOf ( 5 ) , BigInteger . valueOf ( - 12 ) ) , "-5/12" ) ;

passedAll &= testEquals ( "BaseConstructor-3" , new BigRational ( BigInteger . valueOf ( - 30 ) , BigInteger . valueOf ( - 72 ) ) , new BigRational ( BigInteger . valueOf ( - 5 ) , BigInteger . valueOf ( - 12 ) ) , "5/12" ) ;

passedAll &= testEquals ( "BaseConstructor-4" , new BigRational ( BigInteger . valueOf ( 0 ) , BigInteger . valueOf ( 5 ) ) , new BigRational ( BigInteger . valueOf ( 0 ) , BigInteger . valueOf ( - 10 ) ) , "0" ) ;

passedAll &= testTrue ( "Inequality-1" , ! new BigRational ( BigInteger . valueOf ( 5 ) , BigInteger . valueOf ( 12 ) ) . equals ( new BigRational ( BigInteger . valueOf ( - 5 ) , BigInteger . valueOf ( 12 ) ) ) ) ;

passedAll &= testTrue ( "Inequality-2" , ! new BigRational ( BigInteger . valueOf ( 5 ) , BigInteger . valueOf ( 12 ) ) . equals ( new BigRational ( BigInteger . valueOf ( 4 ) , BigInteger . valueOf ( 12 ) ) ) ) ;

passedAll &= testEquals ( "IntegerConstructor-1" , BigRational. valueOf ( 5 ) , "5" ) ;

passedAll &= testEquals ( "IntegerConstructor-2" , BigRational. valueOf ( 5 , 12 ) , new BigRational ( BigInteger . valueOf ( 30 ) , BigInteger . valueOf ( 72 ) ) , "5/12" ) ;

passedAll &= testEquals ( "LongConstructor-1" , BigRational. valueOf ( 10000000000L ) , "10000000000" ) ;

passedAll &= testEquals ( "LongConstructor-2" , BigRational. valueOf ( 50000000000L, 120000000000L ) , new BigRational ( BigInteger . valueOf ( 300000000000L ) , BigInteger . valueOf ( 720000000000L ) ) , "5/12" ) ;

passedAll &= testEquals ( "BigDecimalConstructor-1" , BigRational. valueOf ( new BigDecimal ( "7.3412359" ) ) , "73412359/10000000" ) ;

passedAll &= testEquals ( "BigDecimalConstructor-2" , BigRational. valueOf ( new BigDecimal ( "7.3412359" ) , new BigDecimal ( "2.6876980111" ) ) , BigRational. valueOf ( 15791000 , 5781239 ) , "15791000/5781239" ) ;

// Derived from BigDecimal documentation, 0.1 is exactly 0.1000000000000000055511151231257827021181583404541015625. Simplified via WolframAlpha

passedAll &= testEquals ( "DoubleConstructor-1" , BigRational. valueOf ( 0.1 ) , BigRational. valueOf ( new BigDecimal ( 0.1 ) ) , "3602879701896397/36028797018963968" ) ;

passedAll &= testEquals ( "DoubleConstructor-2" , BigRational. valueOf ( 0.1 , 0.2 ) , BigRational. valueOf ( 1 , 2 ) , "1/2" ) ;

passedAll &= testEquals ( "StringConstructor-1" , BigRational. valueOf ( "18" ) , BigRational. valueOf ( 18 ) , "18" ) ;

passedAll &= testEquals ( "StringConstructor-2" , BigRational. valueOf ( "18/-4" ) , BigRational. valueOf ( 9 , - 2 ) , "-9/2" ) ;

passedAll &= testEquals ( "StringConstructor-3" , BigRational. valueOf ( "18" , "-4" ) , BigRational. valueOf ( 9 , - 2 ) , "-9/2" ) ;

passedAll &= testEquals ( "AbsoluteValue" , BigRational. valueOf ( - 1 , 2 ) . abs ( ) , BigRational. valueOf ( 1 , 2 ) , "1/2" ) ;

passedAll &= testEquals ( "Addition-1" , BigRational. valueOf ( "2/5" ) . add ( BigRational. valueOf ( "3/7" ) ) , "29/35" ) ;

passedAll &= testEquals ( "Addition-2" , BigRational. valueOf ( "2/5" ) . add ( BigRational. valueOf ( "-3/7" ) ) , "-1/35" ) ;

passedAll &= testEquals ( "Addition-3" , BigRational. valueOf ( "-2/5" ) . add ( BigRational. valueOf ( "3/7" ) ) , "1/35" ) ;

passedAll &= testEquals ( "Addition-4" , BigRational. valueOf ( "-2/5" ) . add ( BigRational. valueOf ( "-3/7" ) ) , "-29/35" ) ;

passedAll &= testEquals ( "Addition-5" , BigRational. valueOf ( "2/5" ) . add ( BigRational. valueOf ( "4/5" ) ) , "6/5" ) ;

passedAll &= testEquals ( "Subtraction-1" , BigRational. valueOf ( "2/5" ) . subtract ( BigRational. valueOf ( "3/7" ) ) , "-1/35" ) ;

passedAll &= testEquals ( "Subtraction-2" , BigRational. valueOf ( "2/5" ) . subtract ( BigRational. valueOf ( "-3/7" ) ) , "29/35" ) ;

passedAll &= testEquals ( "Subtraction-3" , BigRational. valueOf ( "-2/5" ) . subtract ( BigRational. valueOf ( "3/7" ) ) , "-29/35" ) ;

passedAll &= testEquals ( "Subtraction-4" , BigRational. valueOf ( "-2/5" ) . subtract ( BigRational. valueOf ( "-3/7" ) ) , "1/35" ) ;

passedAll &= testEquals ( "Subtraction-5" , BigRational. valueOf ( "2/7" ) . subtract ( BigRational. valueOf ( "3/7" ) ) , "-1/7" ) ;

passedAll &= testTrue ( "Comparison-1" , BigRational. valueOf ( "2/5" ) . compareTo ( BigRational. valueOf ( "-2/5" ) ) > 0 ) ;

passedAll &= testTrue ( "Comparison-2" , BigRational. valueOf ( "-2/5" ) . compareTo ( BigRational. valueOf ( "2/5" ) ) < 0 ) ;

passedAll &= testTrue ( "Comparison-3" , BigRational. valueOf ( "2/5" ) . compareTo ( BigRational. valueOf ( "3/7" ) ) < 0 ) ;

passedAll &= testTrue ( "Comparison-4" , BigRational. valueOf ( "-2/5" ) . compareTo ( BigRational. valueOf ( "-3/7" ) ) > 0 ) ;

passedAll &= testEquals ( "Increment-1" , BigRational. valueOf ( "2/5" ) . increment ( ) , "7/5" ) ;

passedAll &= testEquals ( "Increment-2" , BigRational. valueOf ( "-2/5" ) . increment ( ) , "3/5" ) ;

passedAll &= testEquals ( "Increment-3" , BigRational. valueOf ( "-7/5" ) . increment ( ) , "-2/5" ) ;

passedAll &= testEquals ( "Decrement-1" , BigRational. valueOf ( "7/5" ) . decrement ( ) , "2/5" ) ;

passedAll &= testEquals ( "Decrement-2" , BigRational. valueOf ( "2/5" ) . decrement ( ) , "-3/5" ) ;

passedAll &= testEquals ( "Decrement-3" , BigRational. valueOf ( "-2/5" ) . decrement ( ) , "-7/5" ) ;

passedAll &= testEquals ( "Divide-1" , BigRational. valueOf ( "2/5" ) . divide ( BigRational. valueOf ( "3/5" ) ) , "2/3" ) ;

passedAll &= testEquals ( "Divide-2" , BigRational. valueOf ( "-2/5" ) . divide ( BigRational. valueOf ( "3/5" ) ) , "-2/3" ) ;

passedAll &= testEquals ( "Divide-3" , BigRational. valueOf ( "-2/5" ) . divide ( BigRational. valueOf ( "-3/5" ) ) , "2/3" ) ;

passedAll &= testTrue ( "DoubleValue-1" , BigRational. valueOf ( "0.1" ) . doubleValue ( ) == 0.1 ) ;

passedAll &= testTrue ( "DoubleValue-2" , BigRational. valueOf ( "1.1" ) . doubleValue ( ) == 1.1 ) ;

passedAll &= testTrue ( "IntValue-1" , BigRational. valueOf ( "7/3" ) . intValue ( ) == 2 ) ;

passedAll &= testTrue ( "IntValue-2" , BigRational. valueOf ( "8/3" ) . intValue ( ) == 2 ) ;

passedAll &= testTrue ( "IntValue-2" , BigRational. valueOf ( "9/3" ) . intValue ( ) == 3 ) ;

passedAll &= testEquals ( "ToBigDecimal-1" , BigRational. valueOf ( "0/3" ) . toBigDecimal ( 10 , RoundingMode. HALF_EVEN ) , "0.0000000000" ) ;

passedAll &= testEquals ( "ToBigDecimal-2" , BigRational. valueOf ( "1/3" ) . toBigDecimal ( 10 , RoundingMode. HALF_EVEN ) , "0.3333333333" ) ;

passedAll &= testEquals ( "ToBigDecimal-3" , BigRational. valueOf ( "2/3" ) . toBigDecimal ( 10 , RoundingMode. HALF_EVEN ) , "0.6666666667" ) ;

passedAll &= testEquals ( "ToBigDecimal-4" , BigRational. valueOf ( "3/3" ) . toBigDecimal ( 10 , RoundingMode. HALF_EVEN ) , "1.000000000" ) ;

passedAll &= testEquals ( "ToBigDecimal-5" , BigRational. valueOf ( "4/3" ) . toBigDecimal ( 10 , RoundingMode. HALF_EVEN ) , "1.333333333" ) ;

passedAll &= testEquals ( "ToBigDecimal-6" , BigRational. valueOf ( "5/3" ) . toBigDecimal ( 10 , RoundingMode. HALF_EVEN ) , "1.666666667" ) ;

passedAll &= testEquals ( "ToBigDecimal-7" , BigRational. valueOf ( "-1/3" ) . toBigDecimal ( 10 , RoundingMode. HALF_EVEN ) , "-0.3333333333" ) ;

passedAll &= testEquals ( "ToBigDecimal-8" , BigRational. valueOf ( "-2/3" ) . toBigDecimal ( 10 , RoundingMode. HALF_EVEN ) , "-0.6666666667" ) ;

passedAll &= testEquals ( "ToBigDecimal-9" , BigRational. valueOf ( "-3/3" ) . toBigDecimal ( 10 , RoundingMode. HALF_EVEN ) , "-1.000000000" ) ;

passedAll &= testEquals ( "Max-1" , BigRational. valueOf ( "2/5" ) . max ( BigRational. valueOf ( "3/7" ) ) , "3/7" ) ;

passedAll &= testEquals ( "Max-2" , BigRational. valueOf ( "2/5" ) . max ( BigRational. valueOf ( "-3/7" ) ) , "2/5" ) ;

passedAll &= testEquals ( "Max-3" , BigRational. valueOf ( "-2/5" ) . max ( BigRational. valueOf ( "-3/7" ) ) , "-2/5" ) ;

passedAll &= testEquals ( "Min-1" , BigRational. valueOf ( "2/5" ) . min ( BigRational. valueOf ( "3/7" ) ) , "2/5" ) ;

passedAll &= testEquals ( "Min-2" , BigRational. valueOf ( "2/5" ) . min ( BigRational. valueOf ( "-3/7" ) ) , "-3/7" ) ;

passedAll &= testEquals ( "Min-3" , BigRational. valueOf ( "-2/5" ) . min ( BigRational. valueOf ( "-3/7" ) ) , "-3/7" ) ;

Object [ ] mixedFraction1 = BigRational. valueOf ( "7/3" ) . mixedFraction ( ) ;

passedAll &= testEquals ( "MixedFraction-1" , mixedFraction1 [ 0 ] , "2" ) ;

passedAll &= testEquals ( "MixedFraction-2" , mixedFraction1 [ 1 ] , "1/3" ) ;

Object [ ] mixedFraction2 = BigRational. valueOf ( "-7/3" ) . mixedFraction ( ) ;

passedAll &= testEquals ( "MixedFraction-3" , mixedFraction2 [ 0 ] , "-2" ) ;

passedAll &= testEquals ( "MixedFraction-4" , mixedFraction2 [ 1 ] , "-1/3" ) ;

passedAll &= testEquals ( "Multiply-1" , BigRational. valueOf ( "2/3" ) . multiply ( BigRational. valueOf ( "3/5" ) ) , "2/5" ) ;

passedAll &= testEquals ( "Multiply-2" , BigRational. valueOf ( "-2/3" ) . multiply ( BigRational. valueOf ( "3/5" ) ) , "-2/5" ) ;

passedAll &= testEquals ( "Multiply-3" , BigRational. valueOf ( "2/3" ) . multiply ( BigRational. valueOf ( "-3/5" ) ) , "-2/5" ) ;

passedAll &= testEquals ( "Multiply-4" , BigRational. valueOf ( "-2/3" ) . multiply ( BigRational. valueOf ( "-3/5" ) ) , "2/5" ) ;

passedAll &= testEquals ( "Multiply-5" , BigRational. valueOf ( "2/3" ) . multiply ( BigInteger . valueOf ( 4 ) ) , "8/3" ) ;

passedAll &= testEquals ( "Multiply-6" , BigRational. valueOf ( "-2/3" ) . multiply ( BigInteger . valueOf ( 4 ) ) , "-8/3" ) ;

passedAll &= testEquals ( "Multiply-7" , BigRational. valueOf ( "2/3" ) . multiply ( BigInteger . valueOf ( - 4 ) ) , "-8/3" ) ;

passedAll &= testEquals ( "Multiply-8" , BigRational. valueOf ( "-2/3" ) . multiply ( BigInteger . valueOf ( - 4 ) ) , "8/3" ) ;

passedAll &= testEquals ( "Negate-1" , BigRational. valueOf ( "2/3" ) . negate ( ) , "-2/3" ) ;

passedAll &= testEquals ( "Negate-2" , BigRational. valueOf ( "-2/3" ) . negate ( ) , "2/3" ) ;

passedAll &= testEquals ( "Power-1" , BigRational. valueOf ( "2/3" ) . pow ( 3 ) , "8/27" ) ;

passedAll &= testEquals ( "Power-2" , BigRational. valueOf ( "-2/3" ) . pow ( 3 ) , "-8/27" ) ;

passedAll &= testEquals ( "Power-3" , BigRational. valueOf ( "-2/3" ) . pow ( 4 ) , "16/81" ) ;

passedAll &= testEquals ( "Reciprocal-1" , BigRational. valueOf ( "2/3" ) . reciprocal ( ) , "3/2" ) ;

passedAll &= testEquals ( "Reciprocal-2" , BigRational. valueOf ( "-2/3" ) . reciprocal ( ) , "-3/2" ) ;

passedAll &= testEquals ( "Reciprocal-3" , BigRational. valueOf ( "1/7" ) . reciprocal ( ) , "7" ) ;

passedAll &= testEquals ( "Reciprocal-4" , BigRational. valueOf ( "-1/7" ) . reciprocal ( ) , "-7" ) ;

passedAll &= testTrue ( "Signum-1" , BigRational. valueOf ( "1/7" ) . signum ( ) == 1 ) ;

passedAll &= testTrue ( "Signum-2" , BigRational. valueOf ( "0/7" ) . signum ( ) == 0 ) ;

passedAll &= testTrue ( "Signum-3" , BigRational. valueOf ( "-1/7" ) . signum ( ) == - 1 ) ;

passedAll &= testEquals ( "Numerator-1" , BigRational. valueOf ( "2/7" ) . numerator ( ) , "2" ) ;

passedAll &= testEquals ( "Numerator-2" , BigRational. valueOf ( "-2/7" ) . numerator ( ) , "2" ) ;

passedAll &= testEquals ( "Denominator-1" , BigRational. valueOf ( "2/7" ) . denominator ( ) , "7" ) ;

passedAll &= testEquals ( "Denominator-2" , BigRational. valueOf ( "-2/7" ) . denominator ( ) , "7" ) ;



System . out . println ( passedAll ? "Passed all tests" : "FAILURE: DID NOT PASS ALL TESTS" ) ;

return passedAll ;

}



public static void main ( String [ ] args )

{

testFeatures ( ) ;

return ;

}



}

