Project/build/packaging adjustments + version 1.3
[measurements/measurements.git] / src / net / mattmccutchen / measurements / Unit.java
CommitLineData
3f5430db
MM
1package net.mattmccutchen.measurements;
2
3import java.util.*;
4
5public class Unit {
3a3b5f3c
MM
6 public static final Unit SECOND = new Unit("s" , 1.0, 1, 0, 0, 0, 0, 0);
7 public static final Unit METER = new Unit("m" , 1.0, 0, 1, 0, 0, 0, 0);
8 public static final Unit GRAM = new Unit("g" , 1.0, 0, 0, 1, 0, 0, 0);
9 public static final Unit COULOMB = new Unit("coul", 1.0, 0, 0, 0, 1, 0, 0);
10 public static final Unit KELVIN = new Unit("K" , 1.0, 0, 0, 0, 0, 1, 0);
11 public static final Unit MOLE = new Unit("mol" , 1.0, 0, 0, 0, 0, 0, 1);
3f5430db
MM
12
13 public static final Unit[] basicUnits = new Unit[] {
3a3b5f3c 14 SECOND, METER, GRAM, COULOMB, KELVIN, MOLE,
3f5430db
MM
15 }; // Don't mutate
16
3a3b5f3c
MM
17 public static final Unit PERCENT = new Unit("%", 1e-2, 0, 0, 0, 0, 0, 0);
18 public static final Unit NEWTON = new Unit("N", 1e+3,-2, 1, 1, 0, 0, 0);
19 public static final Unit JOULE = new Unit("J", 1e+3,-2, 2, 1, 0, 0, 0);
20 public static final Unit WATT = new Unit("W", 1e+3,-3, 2, 1, 0, 0, 0);
21 public static final Unit VOLT = new Unit("V", 1e+3,-2, 2, 1,-1, 0, 0);
22 public static final Unit AMP = new Unit("A", 1.0 ,-1, 0, 0, 1, 0, 0);
23 public static final Unit LITER = new Unit("L", 1e-3, 0, 3, 0, 0, 0, 0);
3f5430db
MM
24
25 public static final Unit[] allUnits = new Unit[] {
3a3b5f3c
MM
26 SECOND, METER, GRAM, COULOMB, KELVIN, MOLE,
27 PERCENT, NEWTON, JOULE, WATT, VOLT, AMP, LITER,
3f5430db
MM
28 }; // Don't mutate
29
30 public final String symbol;
31 public final double factor;
32 public final int[] powers; // Don't mutate
33
34 private Unit(String symbol, double factor, int... powers) {
35 this.symbol = symbol;
36 this.factor = factor;
37 this.powers = powers;
38 }
39
40 private static final Map<String, Unit> unitsBySymbol; // Don't mutate
41 private static final Map<Character, Double> prefixes; // Don't mutate
42
43 public static Unit lookupBySymbol(String symbol) {
44 Unit u = unitsBySymbol.get(symbol);
45 if (u != null)
46 return u;
47 char pfx = symbol.charAt(0);
48 symbol = symbol.substring(1);
49 u = unitsBySymbol.get(symbol);
50 Double mult1 = prefixes.get(pfx);
51 if (u != null && mult1 != null)
52 return new Unit(symbol, u.factor * mult1, u.powers);
53 return null;
54 }
55
56 static {
57 unitsBySymbol = new LinkedHashMap<String, Unit>();
58 for (Unit u : allUnits)
59 unitsBySymbol.put(u.symbol, u);
60
61 prefixes = new LinkedHashMap<Character, Double>();
62 prefixes.put('k', 1e+03);
63 prefixes.put('M', 1e+06);
64 prefixes.put('G', 1e+09);
65 prefixes.put('T', 1e+12);
66 prefixes.put('P', 1e+15);
67 prefixes.put('E', 1e+18);
68 prefixes.put('Z', 1e+21);
69 prefixes.put('Y', 1e+24);
3a3b5f3c 70 prefixes.put('c', 1e-02);
3f5430db
MM
71 prefixes.put('m', 1e-03);
72 prefixes.put('u', 1e-06); // micro -> u: oh well
73 prefixes.put('n', 1e-09);
74 prefixes.put('p', 1e-12);
75 prefixes.put('f', 1e-15);
76 prefixes.put('a', 1e-18);
77 prefixes.put('z', 1e-21);
78 prefixes.put('y', 1e-24);
79 }
80
81 public static Unit parseUnitString(String ustr) {
82 double fctr = 1;
83 int[] up = new int[Unit.basicUnits.length];
84 StringTokenizer unitT = new StringTokenizer(ustr, " */", true);
85 boolean invert = false;
86 while (unitT.hasMoreTokens()) {
87 String tok = unitT.nextToken();
88 if (tok.equals("/")) {
89 invert = !invert;
90 continue;
91 } else if (tok.equals(" ") || tok.equals("*"))
92 continue;
93 int caret = tok.indexOf('^');
94 String symbol;
95 int power;
96 if (caret == -1) {
97 power = 1;
98 symbol = tok;
99 } else {
100 power = Integer.parseInt(tok.substring(caret + 1));
101 symbol = tok.substring(0, caret);
102 }
103 Unit unit = Unit.lookupBySymbol(symbol);
104 if (unit == null)
105 throw new NullPointerException();
106 if (invert)
107 power = -power;
108 fctr *= Math.pow(unit.factor, power);
109 for (int i = 0; i < Unit.basicUnits.length; i++)
110 up[i] += power * unit.powers[i];
111 }
112 return new Unit(ustr, fctr, up);
113 }
114}