KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > lsmp > djep > groupJep > values > Rational


1 /* @author rich
2  * Created on 05-Mar-2004
3  *
4  * This code is covered by a Creative Commons
5  * Attribution, Non Commercial, Share Alike license
6  * <a HREF="http://creativecommons.org/licenses/by-nc-sa/1.0">License</a>
7  */

8 package org.lsmp.djep.groupJep.values;
9 import java.math.*;
10 /**
11  * A Rational number with full precision. Represented as quotien of two
12  * numbers (always in most reduced form with posative denominator).
13  *
14  * @author Rich Morris
15  * Created on 05-Mar-2004
16  */

17 public class Rational extends Number JavaDoc implements Comparable JavaDoc {
18
19     private BigInteger numerator;
20     private BigInteger denominator;
21     /**
22      */

23     private Rational() { }
24     
25     public Rational(BigInteger num) {
26         numerator = num; denominator = BigInteger.ONE;
27     }
28     
29     /** Rationals will always be represented in most reduced
30      * form with a positive denominator.
31      */

32     public Rational(BigInteger num,BigInteger den) {
33         BigInteger gcd = num.gcd(den);
34         if(gcd.equals(BigInteger.ZERO)) {
35             numerator = denominator = BigInteger.ZERO;
36         }
37         else if(den.signum() > 0){
38             numerator = num.divide(gcd);
39             denominator = den.divide(gcd);
40         }
41         else {
42             numerator = num.divide(gcd).negate();
43             denominator = den.divide(gcd).negate();
44         }
45     }
46     
47     public int intValue()
48     {
49         if(denominator.equals(BigInteger.ZERO))
50         {
51             int sign = numerator.signum();
52             if(sign == 0)
53                 return Integer.MAX_VALUE;
54             else if(sign > 0 )
55                 return Integer.MAX_VALUE;
56             else
57                 return Integer.MIN_VALUE;
58         }
59         return numerator.divide(denominator).intValue();
60     }
61     public long longValue()
62     {
63         return numerator.divide(denominator).longValue();
64     }
65     public float floatValue()
66     {
67         if(denominator.equals(BigInteger.ZERO))
68         {
69             int sign = numerator.signum();
70             if(sign == 0)
71                 return Float.NaN;
72             else if(sign > 0 )
73                 return Float.POSITIVE_INFINITY;
74             else
75                 return Float.NEGATIVE_INFINITY;
76         }
77         return numerator.divide(denominator).floatValue();
78     }
79     public double doubleValue()
80     {
81         if(denominator.equals(BigInteger.ZERO))
82         {
83             int sign = numerator.signum();
84             if(sign == 0)
85                 return Double.NaN;
86             else if(sign > 0 )
87                 return Double.POSITIVE_INFINITY;
88             else
89                 return Double.NEGATIVE_INFINITY;
90         }
91         return numerator.divide(denominator).doubleValue();
92     }
93     
94     public Rational add(Rational arg)
95     {
96         BigInteger ad = this.numerator.multiply(arg.denominator);
97         BigInteger bc = this.denominator.multiply(arg.numerator);
98         BigInteger bd = this.denominator.multiply(arg.denominator);
99         BigInteger top = ad.add(bc);
100         return new Rational(top,bd);
101     }
102
103     public Rational sub(Rational arg)
104     {
105         BigInteger ad = this.numerator.multiply(arg.denominator);
106         BigInteger bc = this.denominator.multiply(arg.numerator);
107         BigInteger bd = this.denominator.multiply(arg.denominator);
108         BigInteger top = ad.subtract(bc);
109         return new Rational(top,bd);
110     }
111
112     public Rational mul(Rational arg)
113     {
114         BigInteger ac = this.numerator.multiply(arg.numerator);
115         BigInteger bd = this.denominator.multiply(arg.denominator);
116         return new Rational(ac,bd);
117     }
118
119     public Rational div(Rational arg)
120     {
121         BigInteger ad = this.numerator.multiply(arg.denominator);
122         BigInteger bc = this.denominator.multiply(arg.numerator);
123         return new Rational(ad,bc);
124     }
125     
126     public Rational pow(Rational arg)
127     {
128         if(!arg.denominator.equals(BigInteger.ONE))
129             throw new ArithmeticException JavaDoc("Can only raise rationals to integer powers");
130         int exponant = arg.numerator.intValue();
131         if(exponant == 0)
132             return new Rational(BigInteger.ONE);
133         else if(exponant > 0)
134         {
135             BigInteger top = this.numerator.pow(exponant);
136             BigInteger bot = this.denominator.pow(exponant);
137             return new Rational(top,bot);
138         }
139         else
140         { // (a/b)^(-c) -> (b/a)^c -> (b^c/a^c)
141
BigInteger top = this.numerator.pow(-exponant);
142             BigInteger bot = this.denominator.pow(-exponant);
143             return new Rational(bot,top);
144         }
145     }
146
147     public Rational negate()
148     {
149             return new Rational(numerator.negate(),denominator);
150     }
151     
152     public Rational inverse()
153     {
154             return new Rational(denominator,numerator);
155     }
156     
157     public static Number JavaDoc valueOf(String JavaDoc s) {
158         int pos = s.indexOf('/');
159         if(pos==-1) return new Rational(new BigInteger(s));
160         else
161             return new Rational(
162                 new BigInteger(s.substring(pos-1)),
163                 new BigInteger(s.substring(pos+1,-1)));
164     }
165     /**
166      * * Returns the bottom half of the rational.
167      */

168     public BigInteger getDenominator() {
169         return denominator;
170     }
171
172     /**
173      * Returns the top half of the rational.
174      */

175     public BigInteger getNumerator() {
176         return numerator;
177     }
178
179     public String JavaDoc toString() {
180         if(denominator.equals(BigInteger.ONE))
181             return numerator.toString();
182         else
183             return numerator.toString() +"/" + denominator.toString();
184     }
185     
186     public int compareTo(Object JavaDoc arg)
187     {
188         Rational num = (Rational) arg;
189         if(this.denominator.compareTo(num.denominator) == 0)
190         {
191             return this.numerator.compareTo(num.numerator);
192         }
193         BigInteger ad = this.numerator.multiply(num.denominator);
194         BigInteger bc = this.denominator.multiply(num.numerator);
195         return ad.compareTo(bc);
196     }
197 }
198
Popular Tags