Java API By Example, From Geeks To Geeks.

# Java > Open Source Codes > gnu > math > RatNum

 `1 // Copyright (c) 1997 Per M.A. Bothner.2 // This is free software; for terms and warranty disclaimer see ./COPYING.3 4 package gnu.math;5 6 /** The abstract class of rational numbers. */7 8 public abstract class RatNum extends RealNum9 {10   public abstract IntNum numerator ();11   public abstract IntNum denominator ();12 13   public static RatNum make(IntNum num, IntNum den)14   {15     IntNum g = IntNum.gcd (num, den);16     if (den.isNegative ())17       g = IntNum.neg (g);18     if (! g.isOne ())19       {20     num = IntNum.quotient (num, g);21     den = IntNum.quotient (den, g);22       }23     return den.isOne () ? (RatNum)num : (RatNum)(new IntFraction (num, den));24   }25 26   public boolean isExact ()27   {28     return true;29   }30 31   public boolean isZero ()32   {33     return numerator().isZero();34   }35 36   /** Return exact "rational" infinity.37   * @param sign either 1 or -1 for positive or negative infinity */38   public static RatNum infinity(int sign)39   {40     return new IntFraction (IntNum.make(sign), IntNum.zero());41   }42 43   public static int compare (RatNum x, RatNum y)44   {45     return IntNum.compare (IntNum.times (x.numerator (), y.denominator ()),46                IntNum.times (y.numerator (), x.denominator ()));47   }48 49   /* Assumes x and y are both canonicalized. */50   public static boolean equals (RatNum x, RatNum y)51   {52     return IntNum.equals (x.numerator(), y.numerator())53       && IntNum.equals (x.denominator(), y.denominator());54   }55 56   /* Assumes this and obj are both canonicalized. */57   public boolean equals (Object obj)58   {59     if (obj == null || ! (obj instanceof RatNum))60       return false;61     return RatNum.equals (this, (RatNum) obj);62   }63 64   public static RatNum add (RatNum x, RatNum y, int k)65   {66     IntNum x_num = x.numerator();67     IntNum x_den = x.denominator();68     IntNum y_num = y.numerator();69     IntNum y_den = y.denominator();70     if (IntNum.equals (x_den, y_den))71       return RatNum.make (IntNum.add (x_num, y_num, k), x_den);72     return RatNum.make (IntNum.add (IntNum.times (y_den, x_num),73                     IntNum.times (y_num, x_den), k),74             IntNum.times (x_den, y_den));75   }76 77   public static RatNum times (RatNum x, RatNum y)78   {79     return RatNum.make (IntNum.times (x.numerator(), y.numerator()),80             IntNum.times (x.denominator(), y.denominator()));81   }82 83   public static RatNum divide (RatNum x, RatNum y)84   {85     return RatNum.make (IntNum.times (x.numerator(), y.denominator()),86             IntNum.times (x.denominator(), y.numerator()));87   }88 89   public Numeric power (IntNum y)90   {91     boolean inv;92     if (y.isNegative())93       {94     inv = true;95     y = IntNum.neg(y);96       }97     else98       inv = false;99     if (y.words == null)100       {101     IntNum num = IntNum.power (numerator(), y.ival);102     IntNum den = IntNum.power (denominator(), y.ival);103     return inv ? RatNum.make (den, num) : RatNum.make (num, den);104       }105     double d = doubleValue();106     boolean neg = d < 0.0 && y.isOdd();107     d = Math.pow (d, y.doubleValue());108     if (inv)109       d = 1.0/d;110     return new DFloNum (neg ? -d : d);111   }112 113   public final RatNum toExact ()114   {115     return this;116   }117 118   public RealNum toInt (int rounding_mode)119   {120     return IntNum.quotient (numerator(), denominator(), rounding_mode);121   }122 123   public IntNum toExactInt (int rounding_mode)124   {125     return IntNum.quotient (numerator(), denominator(), rounding_mode);126   }127 128   /** Calcaulte the simplest rational between two reals. */129   public static RealNum rationalize (RealNum x, RealNum y)130   {131     // This algorithm is by Alan Bawden. It has been transcribed132 // with permission from C-Gambit, copyright Marc Feeley.133 if (x.grt (y))134       return simplest_rational2 (y, x);135     else if (! (y.grt(x)))136       return x;137     else if (x.sign() > 0)138       return simplest_rational2 (x, y);139     else if (y.isNegative ())140       return (RealNum) (simplest_rational2 ((RealNum)y.neg(),141                         (RealNum)x.neg())).neg();142     else143       return IntNum.zero ();144   }145   private static RealNum simplest_rational2 (RealNum x, RealNum y)146   {147     RealNum fx = x.toInt (FLOOR);148     RealNum fy = y.toInt (FLOOR);149     if (! x.grt(fx))150       return fx;151     else if (fx.equals(fy))152       {153     RealNum n = (RealNum) IntNum.one().div(y.sub(fy));154     RealNum d = (RealNum) IntNum.one().div(x.sub(fx));155     return (RealNum) fx.add(IntNum.one().div(simplest_rational2 (n, d)),156                 1);157       }158     else159       return (RealNum) fx.add(IntNum.one(), 1);160   }161 }162 ` Popular Tags