123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- // Copyright (c) 1997 Per M.A. Bothner.
- // This is free software; for terms and warranty disclaimer see ./COPYING.
- package gnu.math;
- /* A unit of measurement, either primitive (meter) or derived (kilogram).
- * @author Per Bothner
- */
- public abstract class Unit extends Quantity
- {
- Dimensions dims;
- /** The value of this Unit is factor*dims. */
- double factor;
- MulUnit products;
- /** A Unit equivalent to this unit, divided by factor.
- Same as the value of the dimensions() only. */
- Unit base;
- /** A hash table of named Units. */
- static NamedUnit[] table = new NamedUnit[100];
- public final Dimensions dimensions() { return dims; }
- public final double doubleValue() { return factor; }
- public int hashCode () { return dims.hashCode (); }
- public String getName() { return null; }
- static Unit times(Unit unit1, int power1, Unit unit2, int power2)
- {
- // First try various simplifications.
- if (unit1 == unit2)
- {
- power1 += power2;
- unit2 = Unit.Empty;
- power2 = 0;
- }
- if (power1 == 0 || unit1 == Unit.Empty)
- {
- unit1 = unit2;
- power1 = power2;
- unit2 = Unit.Empty;
- power2 = 0;
- }
- if (power2 == 0 || unit2 == Unit.Empty)
- {
- if (power1 == 1)
- return unit1;
- if (power1 == 0)
- return Unit.Empty;
- }
- if (unit1 instanceof MulUnit)
- {
- MulUnit munit1 = (MulUnit) unit1;
- if (munit1.unit1 == unit2)
- return times(unit2, munit1.power1 * power1 + power2,
- munit1.unit2, munit1.power2 * power1);
- if (munit1.unit2 == unit2)
- return times(munit1.unit1, munit1.power1 * power1,
- unit2, munit1.power2 * power1 + power2);
- if (unit2 instanceof MulUnit)
- {
- MulUnit munit2 = (MulUnit) unit2;
- if (munit1.unit1 == munit2.unit1 && munit1.unit2 == munit2.unit2)
- return times(munit1.unit1,
- munit1.power1 * power1 + munit2.power1 * power2,
- munit1.unit2,
- munit1.power2 * power1 + munit2.power2 * power2);
- if (munit1.unit1 == munit2.unit2 && munit1.unit2 == munit2.unit1)
- return times(munit1.unit1,
- munit1.power1 * power1 + munit2.power2 * power2,
- munit1.unit2,
- munit1.power2 * power1 + munit2.power1 * power2);
- }
- }
- if (unit2 instanceof MulUnit)
- {
- MulUnit munit2 = (MulUnit) unit2;
- if (munit2.unit1 == unit1)
- return times(unit1, power1 + munit2.power1 * power2,
- munit2.unit2, munit2.power2 * power2);
- if (munit2.unit2 == unit1)
- return times(munit2.unit1, munit2.power1 * power2,
- unit1, power1 + munit2.power2 * power2);
- }
- return MulUnit.make(unit1, power1, unit2, power2);
- }
- public static Unit times(Unit unit1, Unit unit2)
- {
- return times(unit1, 1, unit2, 1);
- }
- public static Unit divide (Unit unit1, Unit unit2)
- {
- return times(unit1, 1, unit2, -1);
- }
- public static Unit pow (Unit unit, int power)
- {
- return times(unit, power, Unit.Empty, 0);
- }
- Unit ()
- {
- factor = 1.0;
- }
- public static NamedUnit make (String name, Quantity value)
- {
- return NamedUnit.make(name, value);
- }
- public static Unit define (String name, DQuantity value)
- {
- return new NamedUnit (name, value);
- }
- public static Unit define (String name, double factor, Unit base)
- {
- return new NamedUnit (name, factor, base);
- }
- public Complex number() { return DFloNum.one(); }
- public boolean isExact () { return false; }
- public final boolean isZero () { return false; }
- public Numeric power (IntNum y)
- {
- if (y.words != null)
- throw new ArithmeticException("Unit raised to bignum power");
- return pow (this, y.ival);
- }
- public Unit sqrt ()
- {
- if (this == Unit.Empty)
- return this;
- throw new RuntimeException ("unimplemented Unit.sqrt");
- }
- public static BaseUnit Empty = new BaseUnit();
- static { Dimensions.Empty.bases[0] = Empty; }
- public static NamedUnit lookup (String name)
- {
- return NamedUnit.lookup(name);
- }
- public String toString (double val)
- {
- String str = Double.toString(val);
- if (this == Unit.Empty)
- return str;
- else
- return str + this.toString();
- }
- public String toString (RealNum val)
- {
- return toString (val.doubleValue());
- }
- /*
- public String toString (Complex val)
- {
- String str = toString(val.re());
- RealNum im = val.im();
- if (im.isZero())
- return str;
- // This conflicts with using '@' for polar notation.
- return str + "@" + toString(im);
- }
- */
- public String toString ()
- {
- String name = getName();
- if (name != null)
- return name;
- else if (this == Unit.Empty)
- return "unit";
- else
- return Double.toString(factor) + "<unnamed unit>";
- }
- public Unit unit ()
- {
- return this;
- }
- /** A magic factor to indicate units that have the same "dimension"
- * but not a fixed multiple.
- * E.g. "month" and "day", or money of different currencies.
- * Since they have the same dimension, they can be added to get
- * an (unimplemented) combined quantity, but they cannot be compared.
- * No general support yet, but used for time Duration.
- */
- public static double NON_COMBINABLE = 0.0;
- public static final BaseUnit meter = new BaseUnit ("m", "Length");
- public static final BaseUnit duration = new BaseUnit ("duration", "Time");
- public static final BaseUnit gram = new BaseUnit ("g", "Mass");
- public static final Unit cm = define("cm", 0.01, meter);
- public static final Unit mm = define("mm", 0.1, cm);
- public static final Unit in = define("in", 0.0254, meter);
- public static final Unit pt = define("pt", 0.0003527778, meter);
- public static final Unit pica = define("pica", 0.004233333, meter);
- public static final Unit radian = define("rad", 1.0, Unit.Empty);
- public static final Unit degree = define("deg", Math.PI/180, Unit.Empty);
- public static final Unit gradian = define("grad", Math.PI/200, Unit.Empty);
- public static final NamedUnit date =
- new NamedUnit("date", NON_COMBINABLE, duration);
- public static final NamedUnit second =
- new NamedUnit("s", NON_COMBINABLE, duration);
- public static final NamedUnit month =
- new NamedUnit("month", NON_COMBINABLE, duration);
- public static final Unit minute = define("min", 60.0, second);
- public static final Unit hour = define("hour", 60.0, minute);
- }
|