KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > measure > converters > RationalConverter


1 /*
2  * JScience - Java(TM) Tools and Libraries for the Advancement of Sciences.
3  * Copyright (C) 2006 - JScience (http://jscience.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */

9 package javax.measure.converters;
10
11 /**
12  * <p> This class represents a converter multiplying numeric values by an
13  * exact scaling factor (represented as the quotient of two
14  * <code>long</code> numbers).</p>
15  *
16  * <p> Instances of this class are immutable.</p>
17  *
18  * @author <a HREF="mailto:jean-marie@dautelle.com">Jean-Marie Dautelle</a>
19  * @version 3.1, April 22, 2006
20  */

21 public final class RationalConverter extends UnitConverter {
22
23     /**
24      * Holds the converter dividend.
25      */

26     private final long _dividend;
27
28     /**
29      * Holds the converter divisor (always positive).
30      */

31     private final long _divisor;
32
33     /**
34      * Creates a rational converter with the specified dividend and
35      * divisor.
36      *
37      * @param dividend the dividend.
38      * @param divisor the positive divisor.
39      * @throws IllegalArgumentException if <code>divisor &lt; 0</code>
40      * @throws IllegalArgumentException if <code>dividend == divisor</code>
41      */

42     public RationalConverter(long dividend, long divisor) {
43         if (divisor < 0)
44             throw new IllegalArgumentException JavaDoc("Negative divisor");
45         if (dividend == divisor)
46             throw new IllegalArgumentException JavaDoc("Identity converter not allowed");
47         _dividend = dividend;
48         _divisor = divisor;
49     }
50
51     /**
52      * Returns the dividend for this rational converter.
53      *
54      * @return this converter dividend.
55      */

56     public long getDividend() {
57         return _dividend;
58     }
59
60     /**
61      * Returns the positive divisor for this rational converter.
62      *
63      * @return this converter divisor.
64      */

65     public long getDivisor() {
66         return _divisor;
67     }
68
69     @Override JavaDoc
70     public UnitConverter inverse() {
71         return _dividend < 0 ? new RationalConverter(-_divisor, -_dividend)
72                 : new RationalConverter(_divisor, _dividend);
73     }
74
75     @Override JavaDoc
76     public double convert(double amount) {
77         return amount * _dividend / _divisor;
78     }
79
80     @Override JavaDoc
81     public boolean isLinear() {
82         return true;
83     }
84
85     @Override JavaDoc
86     public boolean equals(Object JavaDoc cvtr) {
87         if (!(cvtr instanceof RationalConverter))
88             return false;
89         RationalConverter rc = (RationalConverter) cvtr;
90         return (_dividend == rc._dividend) && (_divisor == rc._divisor);
91     }
92
93     @Override JavaDoc
94     public int hashCode() {
95         long value = _dividend - _divisor;
96         int h = (int) (value ^ (value >>> 32));
97         h += ~(h << 9);
98         h ^= (h >>> 14);
99         h += (h << 4);
100         return h ^ (h >>> 10);
101     }
102
103     @Override JavaDoc
104     public UnitConverter concatenate(UnitConverter converter) {
105         if (converter instanceof RationalConverter) {
106             RationalConverter that = (RationalConverter) converter;
107             long dividendLong = this._dividend * that._dividend;
108             long divisorLong = this._divisor * that._divisor;
109             double dividendDouble = ((double)this._dividend) * that._dividend;
110             double divisorDouble = ((double)this._divisor) * that._divisor;
111             if ((dividendLong != dividendDouble) ||
112                     (divisorLong != divisorDouble)) { // Long overflows.
113
return new MultiplyConverter(dividendDouble / divisorDouble);
114             }
115             long gcd = gcd(dividendLong, divisorLong);
116             return RationalConverter.valueOf(dividendLong / gcd, divisorLong / gcd);
117         } else if (converter instanceof MultiplyConverter) {
118             return converter.concatenate(this);
119         } else {
120             return super.concatenate(converter);
121         }
122     }
123
124     private static UnitConverter valueOf(long dividend, long divisor) {
125         return (dividend == 1L) && (divisor == 1L) ? UnitConverter.IDENTITY
126                 : new RationalConverter(dividend, divisor);
127     }
128
129     /**
130      * Returns the greatest common divisor (Euclid's algorithm).
131      *
132      * @param m the first number.
133      * @param nn the second number.
134      * @return the greatest common divisor.
135      */

136     private static long gcd(long m, long n) {
137         if (n == 0L) {
138             return m;
139         } else {
140             return gcd(n, m % n);
141         }
142     }
143
144     private static final long serialVersionUID = 1L;
145 }
Popular Tags