1 4 package gnu.math; 5 6 11 12 public class Dimensions 13 { 14 17 BaseUnit[] bases; 18 19 21 short[] powers; 22 23 int hash_code; 24 25 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 41 public static Dimensions Empty = new Dimensions (); 42 43 private Dimensions () 45 { 46 bases = new BaseUnit[1]; 47 bases[0] = Unit.Empty; 48 enterHash (0); 49 } 50 51 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 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 ("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 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 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 toString () 170 { 171 StringBuffer buf = new StringBuffer (); 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 |