1 package net.mattmccutchen.measurements;
6 public static final Unit SECOND = new Unit("s" , 1.0, 1, 0, 0, 0, 0);
7 public static final Unit METER = new Unit("m" , 1.0, 0, 1, 0, 0, 0);
8 public static final Unit GRAM = new Unit("g" , 1.0, 0, 0, 1, 0, 0);
9 public static final Unit COULOMB = new Unit("coul", 1.0, 0, 0, 0, 1, 0);
10 public static final Unit KELVIN = new Unit("K" , 1.0, 0, 0, 0, 0, 1);
12 public static final Unit[] basicUnits = new Unit[] {
13 SECOND, METER, GRAM, COULOMB, KELVIN,
16 public static final Unit LITER = new Unit("L", 1e-3, 0, 3, 0, 0, 0);
17 public static final Unit PERCENT = new Unit("%", 1e-2, 0, 0, 0, 0, 0);
19 public static final Unit[] allUnits = new Unit[] {
20 PERCENT, SECOND, METER, GRAM, COULOMB, KELVIN, LITER,
23 public final String symbol;
24 public final double factor;
25 public final int[] powers; // Don't mutate
27 private Unit(String symbol, double factor, int... powers) {
33 private static final Map<String, Unit> unitsBySymbol; // Don't mutate
34 private static final Map<Character, Double> prefixes; // Don't mutate
36 public static Unit lookupBySymbol(String symbol) {
37 Unit u = unitsBySymbol.get(symbol);
40 char pfx = symbol.charAt(0);
41 symbol = symbol.substring(1);
42 u = unitsBySymbol.get(symbol);
43 Double mult1 = prefixes.get(pfx);
44 if (u != null && mult1 != null)
45 return new Unit(symbol, u.factor * mult1, u.powers);
50 unitsBySymbol = new LinkedHashMap<String, Unit>();
51 for (Unit u : allUnits)
52 unitsBySymbol.put(u.symbol, u);
54 prefixes = new LinkedHashMap<Character, Double>();
55 prefixes.put('k', 1e+03);
56 prefixes.put('M', 1e+06);
57 prefixes.put('G', 1e+09);
58 prefixes.put('T', 1e+12);
59 prefixes.put('P', 1e+15);
60 prefixes.put('E', 1e+18);
61 prefixes.put('Z', 1e+21);
62 prefixes.put('Y', 1e+24);
63 prefixes.put('m', 1e-03);
64 prefixes.put('u', 1e-06); // micro -> u: oh well
65 prefixes.put('n', 1e-09);
66 prefixes.put('p', 1e-12);
67 prefixes.put('f', 1e-15);
68 prefixes.put('a', 1e-18);
69 prefixes.put('z', 1e-21);
70 prefixes.put('y', 1e-24);
73 public static Unit parseUnitString(String ustr) {
75 int[] up = new int[Unit.basicUnits.length];
76 StringTokenizer unitT = new StringTokenizer(ustr, " */", true);
77 boolean invert = false;
78 while (unitT.hasMoreTokens()) {
79 String tok = unitT.nextToken();
80 if (tok.equals("/")) {
83 } else if (tok.equals(" ") || tok.equals("*"))
85 int caret = tok.indexOf('^');
92 power = Integer.parseInt(tok.substring(caret + 1));
93 symbol = tok.substring(0, caret);
95 Unit unit = Unit.lookupBySymbol(symbol);
97 throw new NullPointerException();
100 fctr *= Math.pow(unit.factor, power);
101 for (int i = 0; i < Unit.basicUnits.length; i++)
102 up[i] += power * unit.powers[i];
104 return new Unit(ustr, fctr, up);