KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > math > Dimensions


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 /** A Dimensions object represents the product or ratio of BaseUnits.
7  * The idea is that in order to add two Quantities (such as 3mm + 5cm)
8  * their Dimensions have to match. Equal dimensions are also ==.
9  * @author Per Bothner.
10  */

11
12 public class Dimensions
13 {
14   /** The BaseUnits that this dimension is defined in terms of.
15    * The BaseUnits are in order of their index, and the last
16    * element is Unit.Empty. */

17   BaseUnit[] bases;
18   
19   /** For each baseunit in bases[i], powers[i] is the corresponding exponent.
20    * It is never zero (as long as i is less than the index of Unit.Empty). */

21   short[] powers;
22
23   int hash_code;
24
25   /* Points to the next Dimension in the same has bucket of hashTable. */
26   private Dimensions chain;
27
28   private static Dimensions[] hashTable = new Dimensions[100];
29
30   public final int hashCode () { return hash_code; }
31
32   private void enterHash (int hash_code)
33   {
34     this.hash_code = hash_code;
35     int index = (hash_code & 0x7FFFFFFF) % hashTable.length;
36     chain = hashTable[index];
37     hashTable[index] = this;
38   }
39
40   /** The empty Dimensions that pure numbers have. */
41   public static Dimensions Empty = new Dimensions ();
42
43   // Only used to create Dimensions.Empty. */
44
private Dimensions ()
45   {
46     bases = new BaseUnit[1];
47     bases[0] = Unit.Empty;
48     enterHash (0);
49   }
50
51   /* Only used by BaseUnit constructor. */
52   Dimensions (BaseUnit unit)
53   {
54     bases = new BaseUnit[2];
55     powers = new short[1];
56     bases[0] = unit;
57     bases[1] = Unit.Empty;
58     powers[0] = 1;
59     enterHash (unit.index);
60   }
61
62   /** Create a new Dimensions corresponding to a^mul_a*b^mul_b. */
63   private Dimensions (Dimensions a, int mul_a, Dimensions b, int mul_b,
64               int hash_code)
65   {
66     int a_i = 0, b_i = 0;
67     this.hash_code = hash_code;
68     for (a_i = 0; a.bases[a_i] != Unit.Empty; a_i++) ;
69     for (b_i = 0; b.bases[b_i] != Unit.Empty; b_i++) ;
70     int t_i = a_i + b_i + 1;
71     bases = new BaseUnit[t_i];
72     powers = new short[t_i];
73     a_i = b_i = t_i = 0;
74     for (;;)
75       {
76     BaseUnit a_base = a.bases[a_i];
77     BaseUnit b_base = b.bases[b_i];
78     int pow;
79     if (a_base.index < b_base.index)
80       {
81         pow = a.powers[a_i] * mul_a;
82         a_i++;
83       }
84     else if (b_base.index < a_base.index)
85       {
86         a_base = b_base;
87         pow = b.powers[b_i] * mul_b;
88         b_i++;
89       }
90     else if (b_base == Unit.Empty)
91       break;
92     else
93       {
94         pow = a.powers[a_i] * mul_a + b.powers[b_i] * mul_b;
95         a_i++; b_i++;
96         if (pow == 0)
97           continue;
98       }
99     if ((short) pow != pow)
100       throw new ArithmeticException JavaDoc ("overflow in dimensions");
101     bases[t_i] = a_base;
102     powers[t_i++] = (short) pow;
103       }
104     bases[t_i] = Unit.Empty;
105     enterHash (hash_code);
106   }
107
108   /** True if this == (a^mul_a)*(b^mul_b). */
109   private boolean matchesProduct (Dimensions a, int mul_a,
110                   Dimensions b, int mul_b)
111   {
112     int a_i = 0, b_i = 0;
113     for (int t_i = 0; ; )
114       {
115     BaseUnit a_base = a.bases[a_i];
116     BaseUnit b_base = b.bases[b_i];
117     int pow;
118     if (a_base.index < b_base.index)
119       {
120         pow = a.powers[a_i] * mul_a;
121         a_i++;
122       }
123     else if (b_base.index < a_base.index)
124       {
125         a_base = b_base;
126         pow = b.powers[b_i] * mul_b;
127         b_i++;
128       }
129     else if (b_base == Unit.Empty)
130       return bases[t_i] == b_base;
131     else
132       {
133         pow = a.powers[a_i] * mul_a + b.powers[b_i] * mul_b;
134         a_i++; b_i++;
135         if (pow == 0)
136           continue;
137       }
138     if (bases[t_i] != a_base || powers[t_i] != pow)
139       return false;
140     t_i++;
141       }
142   }
143
144   public static Dimensions product (Dimensions a, int mul_a,
145                     Dimensions b, int mul_b)
146   {
147     int hash = a.hashCode () * mul_a + b.hashCode () * mul_b;
148     int index = (hash & 0x7FFFFFFF) % hashTable.length;
149     Dimensions dim = hashTable[index];
150     for ( ; dim != null; dim = dim.chain)
151       {
152     if (dim.hash_code == hash && dim.matchesProduct (a, mul_a, b, mul_b))
153       return dim;
154       }
155     return new Dimensions (a, mul_a, b, mul_b, hash);
156   }
157
158   /** Get the exponent for a BaseUnit in this Dimensions object. */
159   public int getPower (BaseUnit unit)
160   {
161     for (int i = 0; bases[i].index <= unit.index; i++)
162       {
163     if (bases[i] == unit)
164       return powers[i];
165       }
166     return 0;
167   }
168
169   public String JavaDoc toString ()
170   {
171     StringBuffer JavaDoc buf = new StringBuffer JavaDoc ();
172     for (int i = 0; bases[i] != Unit.Empty; i++)
173       {
174     if (i > 0)
175       buf.append('*');
176     buf.append (bases[i]);
177     int pow = powers[i];
178     if (pow != 1)
179       {
180         buf.append ('^');
181         buf.append (pow);
182       }
183       }
184     return buf.toString ();
185   }
186 }
187
Popular Tags