001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package org.wpilib.units;
006
007import static org.wpilib.units.Units.Value;
008
009import org.wpilib.units.measure.Acceleration;
010import org.wpilib.units.measure.Angle;
011import org.wpilib.units.measure.AngularAcceleration;
012import org.wpilib.units.measure.AngularMomentum;
013import org.wpilib.units.measure.AngularVelocity;
014import org.wpilib.units.measure.Current;
015import org.wpilib.units.measure.Dimensionless;
016import org.wpilib.units.measure.Distance;
017import org.wpilib.units.measure.Energy;
018import org.wpilib.units.measure.Force;
019import org.wpilib.units.measure.Frequency;
020import org.wpilib.units.measure.LinearAcceleration;
021import org.wpilib.units.measure.LinearMomentum;
022import org.wpilib.units.measure.LinearVelocity;
023import org.wpilib.units.measure.Mass;
024import org.wpilib.units.measure.MomentOfInertia;
025import org.wpilib.units.measure.Mult;
026import org.wpilib.units.measure.Per;
027import org.wpilib.units.measure.Power;
028import org.wpilib.units.measure.Resistance;
029import org.wpilib.units.measure.Temperature;
030import org.wpilib.units.measure.Time;
031import org.wpilib.units.measure.Torque;
032import org.wpilib.units.measure.Velocity;
033import org.wpilib.units.measure.Voltage;
034
035/**
036 * A measure holds the magnitude and unit of some dimension, such as distance, time, or velocity.
037 * Two measures with the same <i>unit</i> and <i>magnitude</i> are effectively equivalent objects.
038 *
039 * @param <U> the unit type of the measure
040 */
041public interface Measure<U extends Unit> extends Comparable<Measure<U>> {
042  /**
043   * The threshold for two measures to be considered equivalent if converted to the same unit. This
044   * is only needed due to floating-point error.
045   */
046  double EQUIVALENCE_THRESHOLD = 1e-12;
047
048  /**
049   * Gets the unitless magnitude of this measure.
050   *
051   * @return the magnitude in terms of {@link #unit() the unit}.
052   */
053  double magnitude();
054
055  /**
056   * Gets the magnitude of this measure in terms of the base unit. If the unit is the base unit for
057   * its system of measure, then the value will be equivalent to {@link #magnitude()}.
058   *
059   * @return the magnitude in terms of the base unit
060   */
061  double baseUnitMagnitude();
062
063  /**
064   * Gets the units of this measure.
065   *
066   * @return the unit
067   */
068  U unit();
069
070  /**
071   * Converts this measure to a measure with a different unit of the same type, eg minutes to
072   * seconds. Converting to the same unit is equivalent to calling {@link #magnitude()}.
073   *
074   * <pre>
075   *   Meters.of(12).in(Feet) // 39.3701
076   *   Seconds.of(15).in(Minutes) // 0.25
077   * </pre>
078   *
079   * @param unit the unit to convert this measure to
080   * @return the value of this measure in the given unit
081   */
082  default double in(U unit) {
083    if (this.unit().equals(unit)) {
084      return magnitude();
085    } else {
086      return unit.fromBaseUnits(baseUnitMagnitude());
087    }
088  }
089
090  /**
091   * A convenience method to get the base unit of the measurement. Equivalent to {@code
092   * unit().getBaseUnit()}.
093   *
094   * @return the base unit of measure.
095   */
096  @SuppressWarnings("unchecked")
097  default U baseUnit() {
098    return (U) unit().getBaseUnit();
099  }
100
101  /**
102   * Absolute value of measure.
103   *
104   * @param unit unit to use
105   * @return the absolute value of this measure in the given unit
106   */
107  default double abs(U unit) {
108    return Math.abs(this.in(unit));
109  }
110
111  /**
112   * Take the sign of another measure.
113   *
114   * @param other measure from which to take sign
115   * @param unit unit to use
116   * @return the value of the measure in the given unit with the sign of the provided measure
117   */
118  default double copySign(Measure<U> other, U unit) {
119    return Math.copySign(this.in(unit), other.in(unit));
120  }
121
122  /**
123   * Returns a measure equivalent to this one equal to zero minus its current value. For non-linear
124   * unit types like temperature, the zero point is treated as the zero value of the base unit (eg
125   * Kelvin). In effect, this means code like {@code Celsius.of(10).unaryMinus()} returns a value
126   * equivalent to -10 Kelvin, and <i>not</i> -10° Celsius.
127   *
128   * @return a measure equal to zero minus this measure
129   */
130  Measure<U> unaryMinus();
131
132  /**
133   * Adds another measure of the same unit type to this one.
134   *
135   * @param other the measurement to add
136   * @return a measure of the sum of both measures
137   */
138  Measure<U> plus(Measure<? extends U> other);
139
140  /**
141   * Subtracts another measure of the same unit type from this one.
142   *
143   * @param other the measurement to subtract
144   * @return a measure of the difference between the measures
145   */
146  Measure<U> minus(Measure<? extends U> other);
147
148  /**
149   * Multiplies this measure by a scalar unitless multiplier.
150   *
151   * @param multiplier the scalar multiplication factor
152   * @return the scaled result
153   */
154  Measure<U> times(double multiplier);
155
156  /**
157   * Multiplies this measure by a scalar dimensionless multiplier.
158   *
159   * @param multiplier the scalar multiplication factor
160   * @return the scaled result
161   */
162  Measure<U> times(Dimensionless multiplier);
163
164  /**
165   * Generates a new measure that is equal to this measure multiplied by another. Some dimensional
166   * analysis is performed to reduce the units down somewhat; for example, multiplying a {@code
167   * Measure<Time>} by a {@code Measure<Velocity<Distance>>} will return just a {@code
168   * Measure<Distance>} instead of the naive {@code Measure<Mult<Time, Velocity<Distance>>}. This is
169   * not guaranteed to perform perfect dimensional analysis.
170   *
171   * @param multiplier the unit to multiply by
172   * @return the multiplicative unit
173   */
174  default Measure<?> times(Measure<?> multiplier) {
175    final double baseUnitResult = baseUnitMagnitude() * multiplier.baseUnitMagnitude();
176
177    // First try to eliminate any common units
178    if (unit() instanceof PerUnit<?, ?> ratio
179        && multiplier.baseUnit().equals(ratio.denominator().getBaseUnit())) {
180      // Per<N, D> * D -> yield N
181      // Case 1: denominator of the Per cancels out, return with just the units of the numerator
182      return ratio.numerator().ofBaseUnits(baseUnitResult);
183    } else if (multiplier.baseUnit() instanceof PerUnit<?, ?> ratio
184        && baseUnit().equals(ratio.denominator().getBaseUnit())) {
185      // D * Per<N, D) -> yield N
186      // Case 2: Same as Case 1, just flipped between this and the multiplier
187      return ratio.numerator().ofBaseUnits(baseUnitResult);
188    } else if (unit() instanceof PerUnit<?, ?> per
189        && multiplier.unit() instanceof PerUnit<?, ?> otherPer
190        && per.denominator().getBaseUnit().equals(otherPer.numerator().getBaseUnit())
191        && per.numerator().getBaseUnit().equals(otherPer.denominator().getBaseUnit())) {
192      // multiplying eg meters per second * milliseconds per foot
193      // return a scalar
194      return Value.of(baseUnitResult);
195    }
196
197    // No common units to eliminate, is one of them dimensionless?
198    // Note that this must come *after* the multiplier cases, otherwise
199    // Per<U, Dimensionless> * Dimensionless will not return a U
200    if (multiplier.unit() instanceof DimensionlessUnit) {
201      // scalar multiplication of this
202      return times(multiplier.baseUnitMagnitude());
203    } else if (unit() instanceof DimensionlessUnit) {
204      // scalar multiplication of multiplier
205      return multiplier.times(baseUnitMagnitude());
206    }
207
208    if (multiplier instanceof Acceleration<?> acceleration) {
209      return times(acceleration);
210    } else if (multiplier instanceof Angle angle) {
211      return times(angle);
212    } else if (multiplier instanceof AngularAcceleration angularAcceleration) {
213      return times(angularAcceleration);
214    } else if (multiplier instanceof AngularMomentum angularMomentum) {
215      return times(angularMomentum);
216    } else if (multiplier instanceof AngularVelocity angularVelocity) {
217      return times(angularVelocity);
218    } else if (multiplier instanceof Current current) {
219      return times(current);
220    } else if (multiplier instanceof Dimensionless dimensionless) {
221      // n.b. this case should already be covered
222      return times(dimensionless);
223    } else if (multiplier instanceof Distance distance) {
224      return times(distance);
225    } else if (multiplier instanceof Energy energy) {
226      return times(energy);
227    } else if (multiplier instanceof Force force) {
228      return times(force);
229    } else if (multiplier instanceof Frequency frequency) {
230      return times(frequency);
231    } else if (multiplier instanceof LinearAcceleration linearAcceleration) {
232      return times(linearAcceleration);
233    } else if (multiplier instanceof LinearVelocity linearVelocity) {
234      return times(linearVelocity);
235    } else if (multiplier instanceof Mass mass) {
236      return times(mass);
237    } else if (multiplier instanceof MomentOfInertia momentOfInertia) {
238      return times(momentOfInertia);
239    } else if (multiplier instanceof Mult<?, ?> mult) {
240      return times(mult);
241    } else if (multiplier instanceof Per<?, ?> per) {
242      return times(per);
243    } else if (multiplier instanceof Power power) {
244      return times(power);
245    } else if (multiplier instanceof Temperature temperature) {
246      return times(temperature);
247    } else if (multiplier instanceof Time time) {
248      return times(time);
249    } else if (multiplier instanceof Torque torque) {
250      return times(torque);
251    } else if (multiplier instanceof Velocity<?> velocity) {
252      return times(velocity);
253    } else if (multiplier instanceof Voltage voltage) {
254      return times(voltage);
255    } else if (multiplier instanceof Resistance resistance) {
256      return times(resistance);
257    } else {
258      // Dimensional analysis fallthrough or a generic input measure type
259      // Do a basic unit multiplication
260      return MultUnit.combine(unit(), multiplier.unit()).ofBaseUnits(baseUnitResult);
261    }
262  }
263
264  /**
265   * Multiplies this measure by an acceleration and returns the resulting measure in the most
266   * appropriate unit.
267   *
268   * @param multiplier the measurement to multiply by.
269   * @return the multiplication result
270   */
271  default Measure<?> times(Acceleration<?> multiplier) {
272    return MultUnit.combine(unit(), multiplier.unit())
273        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
274  }
275
276  /**
277   * Multiplies this measure by an angle and returns the resulting measure in the most appropriate
278   * unit.
279   *
280   * @param multiplier the measurement to multiply by.
281   * @return the multiplication result
282   */
283  default Measure<?> times(Angle multiplier) {
284    return MultUnit.combine(unit(), multiplier.unit())
285        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
286  }
287
288  /**
289   * Multiplies this measure by an angular acceleration and returns the resulting measure in the
290   * most appropriate unit.
291   *
292   * @param multiplier the measurement to multiply by.
293   * @return the multiplication result
294   */
295  default Measure<?> times(AngularAcceleration multiplier) {
296    return MultUnit.combine(unit(), multiplier.unit())
297        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
298  }
299
300  /**
301   * Multiplies this measure by an angular momentum and returns the resulting measure in the most
302   * appropriate unit.
303   *
304   * @param multiplier the measurement to multiply by.
305   * @return the multiplication result
306   */
307  default Measure<?> times(AngularMomentum multiplier) {
308    return MultUnit.combine(unit(), multiplier.unit())
309        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
310  }
311
312  /**
313   * Multiplies this measure by an angular velocity and returns the resulting measure in the most
314   * appropriate unit.
315   *
316   * @param multiplier the measurement to multiply by.
317   * @return the multiplication result
318   */
319  default Measure<?> times(AngularVelocity multiplier) {
320    return MultUnit.combine(unit(), multiplier.unit())
321        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
322  }
323
324  /**
325   * Multiplies this measure by an electric current and returns the resulting measure in the most
326   * appropriate unit.
327   *
328   * @param multiplier the measurement to multiply by.
329   * @return the multiplication result
330   */
331  default Measure<?> times(Current multiplier) {
332    return MultUnit.combine(unit(), multiplier.unit())
333        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
334  }
335
336  /**
337   * Multiplies this measure by a distance and returns the resulting measure in the most appropriate
338   * unit.
339   *
340   * @param multiplier the measurement to multiply by.
341   * @return the multiplication result
342   */
343  default Measure<?> times(Distance multiplier) {
344    return MultUnit.combine(unit(), multiplier.unit())
345        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
346  }
347
348  /**
349   * Multiplies this measure by an energy and returns the resulting measure in the most appropriate
350   * unit.
351   *
352   * @param multiplier the measurement to multiply by.
353   * @return the multiplication result
354   */
355  default Measure<?> times(Energy multiplier) {
356    return MultUnit.combine(unit(), multiplier.unit())
357        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
358  }
359
360  /**
361   * Multiplies this measure by a force and returns the resulting measure in the most appropriate
362   * unit.
363   *
364   * @param multiplier the measurement to multiply by.
365   * @return the multiplication result
366   */
367  default Measure<?> times(Force multiplier) {
368    return MultUnit.combine(unit(), multiplier.unit())
369        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
370  }
371
372  /**
373   * Multiplies this measure by a frequency and returns the resulting measure in the most
374   * appropriate unit. This often - but not always - means implementations return a variation of a
375   * {@link Per} measure.
376   *
377   * @param multiplier the measurement to multiply by.
378   * @return the multiplication result
379   */
380  default Measure<?> times(Frequency multiplier) {
381    return MultUnit.combine(unit(), multiplier.unit())
382        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
383  }
384
385  /**
386   * Multiplies this measure by a linear acceleration and returns the resulting measure in the most
387   * appropriate unit.
388   *
389   * @param multiplier the measurement to multiply by.
390   * @return the multiplication result
391   */
392  default Measure<?> times(LinearAcceleration multiplier) {
393    return MultUnit.combine(unit(), multiplier.unit())
394        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
395  }
396
397  /**
398   * Multiplies this measure by a linear momentum and returns the resulting measure in the most
399   * appropriate unit.
400   *
401   * @param multiplier the measurement to multiply by.
402   * @return the multiplication result
403   */
404  default Measure<?> times(LinearMomentum multiplier) {
405    return MultUnit.combine(unit(), multiplier.unit())
406        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
407  }
408
409  /**
410   * Multiplies this measure by a linear velocity and returns the resulting measure in the most
411   * appropriate unit.
412   *
413   * @param multiplier the measurement to multiply by.
414   * @return the multiplication result
415   */
416  default Measure<?> times(LinearVelocity multiplier) {
417    return MultUnit.combine(unit(), multiplier.unit())
418        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
419  }
420
421  /**
422   * Multiplies this measure by a mass and returns the resulting measure in the most appropriate
423   * unit.
424   *
425   * @param multiplier the measurement to multiply by.
426   * @return the multiplication result
427   */
428  default Measure<?> times(Mass multiplier) {
429    return MultUnit.combine(unit(), multiplier.unit())
430        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
431  }
432
433  /**
434   * Multiplies this measure by a moment of intertia and returns the resulting measure in the most
435   * appropriate unit.
436   *
437   * @param multiplier the measurement to multiply by.
438   * @return the multiplication result
439   */
440  default Measure<?> times(MomentOfInertia multiplier) {
441    return MultUnit.combine(unit(), multiplier.unit())
442        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
443  }
444
445  /**
446   * Multiplies this measure by a generic multiplied measure and returns the resulting measure in
447   * the most appropriate unit.
448   *
449   * @param multiplier the measurement to multiply by.
450   * @return the multiplication result
451   */
452  default Measure<?> times(Mult<?, ?> multiplier) {
453    return MultUnit.combine(unit(), multiplier.unit())
454        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
455  }
456
457  /**
458   * Multiplies this measure by a power and returns the resulting measure in the most appropriate
459   * unit.
460   *
461   * @param multiplier the measurement to multiply by.
462   * @return the multiplication result
463   */
464  default Measure<?> times(Power multiplier) {
465    return MultUnit.combine(unit(), multiplier.unit())
466        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
467  }
468
469  /**
470   * Multiplies this measure by a generic ratio measurement and returns the resulting measure in the
471   * most appropriate unit.
472   *
473   * @param multiplier the measurement to multiply by.
474   * @return the multiplication result
475   */
476  default Measure<?> times(Per<?, ?> multiplier) {
477    return MultUnit.combine(unit(), multiplier.unit())
478        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
479  }
480
481  /**
482   * Multiplies this measure by a temperature and returns the resulting measure in the most
483   * appropriate unit.
484   *
485   * @param multiplier the measurement to multiply by.
486   * @return the multiplication result
487   */
488  default Measure<?> times(Temperature multiplier) {
489    return MultUnit.combine(unit(), multiplier.unit())
490        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
491  }
492
493  /**
494   * Multiplies this measure by a time and returns the resulting measure in the most appropriate
495   * unit.
496   *
497   * @param multiplier the measurement to multiply by.
498   * @return the multiplication result
499   */
500  default Measure<?> times(Time multiplier) {
501    return MultUnit.combine(unit(), multiplier.unit())
502        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
503  }
504
505  /**
506   * Multiplies this measure by a torque and returns the resulting measure in the most appropriate
507   * unit.
508   *
509   * @param multiplier the measurement to multiply by.
510   * @return the multiplication result
511   */
512  default Measure<?> times(Torque multiplier) {
513    return MultUnit.combine(unit(), multiplier.unit())
514        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
515  }
516
517  /**
518   * Multiplies this measure by a generic velocity and returns the resulting measure in the most
519   * appropriate unit.
520   *
521   * @param multiplier the measurement to multiply by.
522   * @return the multiplication result
523   */
524  default Measure<?> times(Velocity<?> multiplier) {
525    return MultUnit.combine(unit(), multiplier.unit())
526        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
527  }
528
529  /**
530   * Multiplies this measure by a voltage and returns the resulting measure in the most appropriate
531   * unit.
532   *
533   * @param multiplier the measurement to multiply by.
534   * @return the multiplication result
535   */
536  default Measure<?> times(Voltage multiplier) {
537    return MultUnit.combine(unit(), multiplier.unit())
538        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
539  }
540
541  /**
542   * Multiplies this measure by a resistance and returns the resulting measure in the most
543   * appropriate unit.
544   *
545   * @param multiplier the measurement to multiply by.
546   * @return the multiplication result
547   */
548  default Measure<?> times(Resistance multiplier) {
549    return MultUnit.combine(unit(), multiplier.unit())
550        .ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
551  }
552
553  /**
554   * Multiplies this measure by a conversion factor, returning the converted measurement. Unlike
555   * {@link #times(Per)}, this allows for basic unit cancellation to return measurements of a known
556   * dimension.
557   *
558   * @param conversionFactor the conversion factor by which to multiply
559   * @param <Other> the unit type to convert to
560   * @param <M> the concrete return unit type. <strong>Note: the conversion factor's numerator unit
561   *     must return instances of this type from {@link Unit#ofBaseUnits(double)}}</strong>
562   * @return the converted result
563   */
564  @SuppressWarnings("unchecked")
565  default <Other extends Unit, M extends Measure<Other>> M timesConversionFactor(
566      Measure<? extends PerUnit<Other, U>> conversionFactor) {
567    return (M)
568        conversionFactor
569            .unit()
570            .getBaseUnit()
571            .numerator()
572            .ofBaseUnits(baseUnitMagnitude() * conversionFactor.baseUnitMagnitude());
573  }
574
575  /**
576   * Multiplies this measure by another measurement of the inverse unit type (eg Time multiplied by
577   * Frequency) and returns the resulting dimensionless measure.
578   *
579   * @param multiplier the measurement to multiply by.
580   * @return the multiplication result
581   */
582  default Dimensionless timesInverse(
583      Measure<? extends PerUnit<DimensionlessUnit, ? extends U>> multiplier) {
584    return Value.ofBaseUnits(baseUnitMagnitude() * multiplier.baseUnitMagnitude());
585  }
586
587  /**
588   * Multiplies this measure by another measurement of something over the unit type (eg Time
589   * multiplied by LinearVelocity) and returns the resulting measure of the ratio's dividend unit.
590   *
591   * @param ratio the measurement to multiply by.
592   * @param <Other> other unit that the results are in terms of
593   * @return the multiplication result
594   */
595  default <Other extends Unit> Measure<Other> timesRatio(
596      Measure<? extends PerUnit<? extends Other, U>> ratio) {
597    return ImmutableMeasure.ofBaseUnits(
598        baseUnitMagnitude() * ratio.baseUnitMagnitude(), ratio.unit().numerator());
599  }
600
601  /**
602   * Divides this measure by a unitless scalar and returns the result.
603   *
604   * @param divisor the measurement to divide by.
605   * @return the division result
606   */
607  Measure<U> div(double divisor);
608
609  /**
610   * Divides this measure by a dimensionless scalar and returns the result.
611   *
612   * @param divisor the measurement to divide by.
613   * @return the division result
614   */
615  Measure<U> div(Dimensionless divisor);
616
617  /**
618   * Divides this measurement by another measure and performs some dimensional analysis to reduce
619   * the units.
620   *
621   * @param divisor the unit to divide by
622   * @return the resulting measure
623   */
624  default Measure<?> div(Measure<?> divisor) {
625    final double baseUnitResult = baseUnitMagnitude() / divisor.baseUnitMagnitude();
626
627    if (unit().getBaseUnit().equals(divisor.unit().getBaseUnit())) {
628      // These are the same unit, return a dimensionless
629      return Value.ofBaseUnits(baseUnitResult);
630    }
631
632    if (divisor instanceof Dimensionless) {
633      // Dividing by a dimensionless, do a scalar division
634      return unit().ofBaseUnits(baseUnitResult);
635    }
636
637    // Numerator is a dimensionless
638    if (unit() instanceof DimensionlessUnit && divisor.unit() instanceof PerUnit<?, ?> ratio) {
639      // Dividing by a ratio, return its reciprocal scaled by this
640      return ratio.reciprocal().ofBaseUnits(baseUnitResult);
641    }
642
643    if (divisor.unit() instanceof PerUnit<?, ?> ratio
644        && ratio.numerator().getBaseUnit().equals(baseUnit())) {
645      // Numerator of the ratio cancels out
646      // N / (N / D) -> N * D / N -> D
647      // Note: all Velocity and Acceleration units inherit from PerUnit
648      return ratio.denominator().ofBaseUnits(baseUnitResult);
649    }
650
651    if (divisor.unit() instanceof TimeUnit time) {
652      // Dividing by a time, return a Velocity
653      return VelocityUnit.combine(unit(), time).ofBaseUnits(baseUnitResult);
654    }
655
656    if (divisor instanceof Acceleration<?> acceleration) {
657      return div(acceleration);
658    } else if (divisor instanceof Angle angle) {
659      return div(angle);
660    } else if (divisor instanceof AngularAcceleration angularAcceleration) {
661      return div(angularAcceleration);
662    } else if (divisor instanceof AngularMomentum angularMomentum) {
663      return div(angularMomentum);
664    } else if (divisor instanceof AngularVelocity angularVelocity) {
665      return div(angularVelocity);
666    } else if (divisor instanceof Current current) {
667      return div(current);
668    } else if (divisor instanceof Dimensionless dimensionless) {
669      // n.b. this case should already be covered
670      return div(dimensionless);
671    } else if (divisor instanceof Distance distance) {
672      return div(distance);
673    } else if (divisor instanceof Energy energy) {
674      return div(energy);
675    } else if (divisor instanceof Force force) {
676      return div(force);
677    } else if (divisor instanceof Frequency frequency) {
678      return div(frequency);
679    } else if (divisor instanceof LinearAcceleration linearAcceleration) {
680      return div(linearAcceleration);
681    } else if (divisor instanceof LinearVelocity linearVelocity) {
682      return div(linearVelocity);
683    } else if (divisor instanceof Mass mass) {
684      return div(mass);
685    } else if (divisor instanceof MomentOfInertia momentOfInertia) {
686      return div(momentOfInertia);
687    } else if (divisor instanceof Mult<?, ?> mult) {
688      return div(mult);
689    } else if (divisor instanceof Per<?, ?> per) {
690      return div(per);
691    } else if (divisor instanceof Power power) {
692      return div(power);
693    } else if (divisor instanceof Temperature temperature) {
694      return div(temperature);
695    } else if (divisor instanceof Time time) {
696      return div(time);
697    } else if (divisor instanceof Torque torque) {
698      return div(torque);
699    } else if (divisor instanceof Velocity<?> velocity) {
700      return div(velocity);
701    } else if (divisor instanceof Voltage voltage) {
702      return div(voltage);
703    } else if (divisor instanceof Resistance resistance) {
704      return div(resistance);
705    } else {
706      // Dimensional analysis fallthrough or a generic input measure type
707      // Do a basic unit multiplication
708      return PerUnit.combine(unit(), divisor.unit()).ofBaseUnits(baseUnitResult);
709    }
710  }
711
712  /**
713   * Divides this measure by a generic acceleration and returns the result in the most appropriate
714   * unit.
715   *
716   * @param divisor the measurement to divide by.
717   * @return the division result
718   */
719  default Measure<?> div(Acceleration<?> divisor) {
720    return PerUnit.combine(unit(), divisor.unit())
721        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
722  }
723
724  /**
725   * Divides this measure by an angle and returns the result in the most appropriate unit.
726   *
727   * @param divisor the measurement to divide by.
728   * @return the division result
729   */
730  default Measure<?> div(Angle divisor) {
731    return PerUnit.combine(unit(), divisor.unit())
732        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
733  }
734
735  /**
736   * Divides this measure by an angular acceleration and returns the result in the most appropriate
737   * unit.
738   *
739   * @param divisor the measurement to divide by.
740   * @return the division result
741   */
742  default Measure<?> div(AngularAcceleration divisor) {
743    return PerUnit.combine(unit(), divisor.unit())
744        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
745  }
746
747  /**
748   * Divides this measure by an angular momentum and returns the result in the most appropriate
749   * unit.
750   *
751   * @param divisor the measurement to divide by.
752   * @return the division result
753   */
754  default Measure<?> div(AngularMomentum divisor) {
755    return PerUnit.combine(unit(), divisor.unit())
756        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
757  }
758
759  /**
760   * Divides this measure by an angular velocity and returns the result in the most appropriate
761   * unit.
762   *
763   * @param divisor the measurement to divide by.
764   * @return the division result
765   */
766  default Measure<?> div(AngularVelocity divisor) {
767    return PerUnit.combine(unit(), divisor.unit())
768        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
769  }
770
771  /**
772   * Divides this measure by an electric current and returns the result in the most appropriate
773   * unit.
774   *
775   * @param divisor the measurement to divide by.
776   * @return the division result
777   */
778  default Measure<?> div(Current divisor) {
779    return PerUnit.combine(unit(), divisor.unit())
780        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
781  }
782
783  /**
784   * Divides this measure by a distance and returns the result in the most appropriate unit.
785   *
786   * @param divisor the measurement to divide by.
787   * @return the division result
788   */
789  default Measure<?> div(Distance divisor) {
790    return PerUnit.combine(unit(), divisor.unit())
791        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
792  }
793
794  /**
795   * Divides this measure by an energy and returns the result in the most appropriate unit.
796   *
797   * @param divisor the measurement to divide by.
798   * @return the division result
799   */
800  default Measure<?> div(Energy divisor) {
801    return PerUnit.combine(unit(), divisor.unit())
802        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
803  }
804
805  /**
806   * Divides this measure by a force and returns the result in the most appropriate unit.
807   *
808   * @param divisor the measurement to divide by.
809   * @return the division result
810   */
811  default Measure<?> div(Force divisor) {
812    return PerUnit.combine(unit(), divisor.unit())
813        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
814  }
815
816  /**
817   * Divides this measure by a frequency and returns the result in the most appropriate unit.
818   *
819   * @param divisor the measurement to divide by.
820   * @return the division result
821   */
822  default Measure<?> div(Frequency divisor) {
823    return PerUnit.combine(unit(), divisor.unit())
824        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
825  }
826
827  /**
828   * Divides this measure by a linear acceleration and returns the result in the most appropriate
829   * unit.
830   *
831   * @param divisor the measurement to divide by.
832   * @return the division result
833   */
834  default Measure<?> div(LinearAcceleration divisor) {
835    return PerUnit.combine(unit(), divisor.unit())
836        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
837  }
838
839  /**
840   * Divides this measure by a linear momentum and returns the result in the most appropriate unit.
841   *
842   * @param divisor the measurement to divide by.
843   * @return the division result
844   */
845  default Measure<?> div(LinearMomentum divisor) {
846    return PerUnit.combine(unit(), divisor.unit())
847        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
848  }
849
850  /**
851   * Divides this measure by a linear velocity and returns the result in the most appropriate unit.
852   *
853   * @param divisor the measurement to divide by.
854   * @return the division result
855   */
856  default Measure<?> div(LinearVelocity divisor) {
857    return PerUnit.combine(unit(), divisor.unit())
858        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
859  }
860
861  /**
862   * Divides this measure by a mass and returns the result in the most appropriate unit.
863   *
864   * @param divisor the measurement to divide by.
865   * @return the division result
866   */
867  default Measure<?> div(Mass divisor) {
868    return PerUnit.combine(unit(), divisor.unit())
869        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
870  }
871
872  /**
873   * Divides this measure by a moment of inertia and returns the result in the most appropriate
874   * unit.
875   *
876   * @param divisor the measurement to divide by.
877   * @return the division result
878   */
879  default Measure<?> div(MomentOfInertia divisor) {
880    return PerUnit.combine(unit(), divisor.unit())
881        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
882  }
883
884  /**
885   * Divides this measure by a generic multiplication and returns the result in the most appropriate
886   * unit.
887   *
888   * @param divisor the measurement to divide by.
889   * @return the division result
890   */
891  default Measure<?> div(Mult<?, ?> divisor) {
892    return PerUnit.combine(unit(), divisor.unit())
893        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
894  }
895
896  /**
897   * Divides this measure by a power and returns the result in the most appropriate unit.
898   *
899   * @param divisor the measurement to divide by.
900   * @return the division result
901   */
902  default Measure<?> div(Power divisor) {
903    return PerUnit.combine(unit(), divisor.unit())
904        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
905  }
906
907  /**
908   * Divides this measure by a generic ratio and returns the result in the most appropriate unit.
909   *
910   * @param divisor the measurement to divide by.
911   * @return the division result
912   */
913  default Measure<?> div(Per<?, ?> divisor) {
914    return PerUnit.combine(unit(), divisor.unit())
915        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
916  }
917
918  /**
919   * Divides this measure by a temperature and returns the result in the most appropriate unit.
920   *
921   * @param divisor the measurement to divide by.
922   * @return the division result
923   */
924  default Measure<?> div(Temperature divisor) {
925    return PerUnit.combine(unit(), divisor.unit())
926        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
927  }
928
929  /**
930   * Divides this measure by a time and returns the result in the most appropriate unit. This will
931   * often - but not always - result in a {@link Per} type like {@link LinearVelocity} or {@link
932   * Acceleration}.
933   *
934   * @param divisor the measurement to divide by.
935   * @return the division result
936   */
937  default Measure<?> div(Time divisor) {
938    return VelocityUnit.combine(unit(), divisor.unit())
939        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
940  }
941
942  /**
943   * Divides this measure by a torque and returns the result in the most appropriate unit.
944   *
945   * @param divisor the measurement to divide by.
946   * @return the division result
947   */
948  default Measure<?> div(Torque divisor) {
949    return PerUnit.combine(unit(), divisor.unit())
950        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
951  }
952
953  /**
954   * Divides this measure by a generic velocity and returns the result in the most appropriate unit.
955   *
956   * @param divisor the measurement to divide by.
957   * @return the division result
958   */
959  default Measure<?> div(Velocity<?> divisor) {
960    return PerUnit.combine(unit(), divisor.unit())
961        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
962  }
963
964  /**
965   * Divides this measure by a voltage and returns the result in the most appropriate unit.
966   *
967   * @param divisor the measurement to divide by.
968   * @return the division result
969   */
970  default Measure<?> div(Voltage divisor) {
971    return PerUnit.combine(unit(), divisor.unit())
972        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
973  }
974
975  /**
976   * Divides this measure by a resistance and returns the result in the most appropriate unit.
977   *
978   * @param divisor the measurement to divide by.
979   * @return the division result
980   */
981  default Measure<?> div(Resistance divisor) {
982    return PerUnit.combine(unit(), divisor.unit())
983        .ofBaseUnits(baseUnitMagnitude() / divisor.baseUnitMagnitude());
984  }
985
986  /**
987   * Divides this measure by an acceleration unit and returns the result in the most appropriate
988   * unit. This is equivalent to {@code div(divisorUnit.of(1))}.
989   *
990   * @param divisorUnit the unit to divide by.
991   * @return the division result
992   */
993  default Measure<?> per(AccelerationUnit<?> divisorUnit) {
994    return div(divisorUnit.one());
995  }
996
997  /**
998   * Divides this measure by an angle unit and returns the result in the most appropriate unit. This
999   * is equivalent to {@code div(divisorUnit.of(1))}.
1000   *
1001   * @param divisorUnit the unit to divide by.
1002   * @return the division result
1003   */
1004  default Measure<?> per(AngleUnit divisorUnit) {
1005    return div(divisorUnit.one());
1006  }
1007
1008  /**
1009   * Divides this measure by an angular acceleration unit and returns the result in the most
1010   * appropriate unit. This is equivalent to {@code div(divisorUnit.of(1))}.
1011   *
1012   * @param divisorUnit the unit to divide by.
1013   * @return the division result
1014   */
1015  default Measure<?> per(AngularAccelerationUnit divisorUnit) {
1016    return div(divisorUnit.one());
1017  }
1018
1019  /**
1020   * Divides this measure by an angular momentum unit and returns the result in the most appropriate
1021   * unit. This is equivalent to {@code div(divisorUnit.of(1))}.
1022   *
1023   * @param divisorUnit the unit to divide by.
1024   * @return the division result
1025   */
1026  default Measure<?> per(AngularMomentumUnit divisorUnit) {
1027    return div(divisorUnit.one());
1028  }
1029
1030  /**
1031   * Divides this measure by an angular velocity unit and returns the result in the most appropriate
1032   * unit. This is equivalent to {@code div(divisorUnit.of(1))}.
1033   *
1034   * @param divisorUnit the unit to divide by.
1035   * @return the division result
1036   */
1037  default Measure<?> per(AngularVelocityUnit divisorUnit) {
1038    return div(divisorUnit.one());
1039  }
1040
1041  /**
1042   * Divides this measure by a unit of electric current and returns the result in the most
1043   * appropriate unit. This is equivalent to {@code div(divisorUnit.of(1))}.
1044   *
1045   * @param divisorUnit the unit to divide by.
1046   * @return the division result
1047   */
1048  default Measure<?> per(CurrentUnit divisorUnit) {
1049    return div(divisorUnit.one());
1050  }
1051
1052  /**
1053   * Divides this measure by a distance unit and returns the result in the most appropriate unit.
1054   * This is equivalent to {@code div(divisorUnit.of(1))}.
1055   *
1056   * @param divisorUnit the unit to divide by.
1057   * @return the division result
1058   */
1059  default Measure<?> per(DistanceUnit divisorUnit) {
1060    return div(divisorUnit.one());
1061  }
1062
1063  /**
1064   * Divides this measure by an energy unit and returns the result in the most appropriate unit.
1065   * This is equivalent to {@code div(divisorUnit.of(1))}.
1066   *
1067   * @param divisorUnit the unit to divide by.
1068   * @return the division result
1069   */
1070  default Measure<?> per(EnergyUnit divisorUnit) {
1071    return div(divisorUnit.one());
1072  }
1073
1074  /**
1075   * Divides this measure by a force unit and returns the result in the most appropriate unit. This
1076   * is equivalent to {@code div(divisorUnit.of(1))}.
1077   *
1078   * @param divisorUnit the unit to divide by.
1079   * @return the division result
1080   */
1081  default Measure<?> per(ForceUnit divisorUnit) {
1082    return div(divisorUnit.one());
1083  }
1084
1085  /**
1086   * Divides this measure by a frequency unit and returns the result in the most appropriate unit.
1087   * This is equivalent to {@code div(divisorUnit.of(1))}.
1088   *
1089   * @param divisorUnit the unit to divide by.
1090   * @return the division result
1091   */
1092  default Measure<?> per(FrequencyUnit divisorUnit) {
1093    return div(divisorUnit.one());
1094  }
1095
1096  /**
1097   * Divides this measure by a linear acceleration unit and returns the result in the most
1098   * appropriate unit. This is equivalent to {@code div(divisorUnit.of(1))}.
1099   *
1100   * @param divisorUnit the unit to divide by.
1101   * @return the division result
1102   */
1103  default Measure<?> per(LinearAccelerationUnit divisorUnit) {
1104    return div(divisorUnit.one());
1105  }
1106
1107  /**
1108   * Divides this measure by a linear momentum unit and returns the result in the most appropriate
1109   * unit. This is equivalent to {@code div(divisorUnit.of(1))}.
1110   *
1111   * @param divisorUnit the unit to divide by.
1112   * @return the division result
1113   */
1114  default Measure<?> per(LinearMomentumUnit divisorUnit) {
1115    return div(divisorUnit.one());
1116  }
1117
1118  /**
1119   * Divides this measure by a linear velocity unit and returns the result in the most appropriate
1120   * unit. This is equivalent to {@code div(divisorUnit.of(1))}.
1121   *
1122   * @param divisorUnit the unit to divide by.
1123   * @return the division result
1124   */
1125  default Measure<?> per(LinearVelocityUnit divisorUnit) {
1126    return div(divisorUnit.one());
1127  }
1128
1129  /**
1130   * Divides this measure by a mass unit and returns the result in the most appropriate unit. This
1131   * is equivalent to {@code div(divisorUnit.of(1))}.
1132   *
1133   * @param divisorUnit the unit to divide by.
1134   * @return the division result
1135   */
1136  default Measure<?> per(MassUnit divisorUnit) {
1137    return div(divisorUnit.one());
1138  }
1139
1140  /**
1141   * Divides this measure by a moment of inertia unit and returns the result in the most appropriate
1142   * unit. This is equivalent to {@code div(divisorUnit.of(1))}.
1143   *
1144   * @param divisorUnit the unit to divide by.
1145   * @return the division result
1146   */
1147  default Measure<?> per(MomentOfInertiaUnit divisorUnit) {
1148    return div(divisorUnit.one());
1149  }
1150
1151  /**
1152   * Divides this measure by a generic compound unit and returns the result in the most appropriate
1153   * unit. This is equivalent to {@code div(divisorUnit.of(1))}.
1154   *
1155   * @param divisorUnit the unit to divide by.
1156   * @return the division result
1157   */
1158  default Measure<?> per(MultUnit<?, ?> divisorUnit) {
1159    return div(divisorUnit.one());
1160  }
1161
1162  /**
1163   * Divides this measure by a power unit and returns the result in the most appropriate unit. This
1164   * is equivalent to {@code div(divisorUnit.of(1))}.
1165   *
1166   * @param divisorUnit the unit to divide by.
1167   * @return the division result
1168   */
1169  default Measure<?> per(PowerUnit divisorUnit) {
1170    return div(divisorUnit.one());
1171  }
1172
1173  /**
1174   * Divides this measure by a generic ratio unit and returns the result in the most appropriate
1175   * unit. This is equivalent to {@code div(divisorUnit.of(1))}.
1176   *
1177   * @param divisorUnit the unit to divide by.
1178   * @return the division result
1179   */
1180  default Measure<?> per(PerUnit<?, ?> divisorUnit) {
1181    return div(divisorUnit.one());
1182  }
1183
1184  /**
1185   * Divides this measure by a temperature unit and returns the result in the most appropriate unit.
1186   * This is equivalent to {@code div(divisorUnit.of(1))}.
1187   *
1188   * @param divisorUnit the unit to divide by.
1189   * @return the division result
1190   */
1191  default Measure<?> per(TemperatureUnit divisorUnit) {
1192    return div(divisorUnit.one());
1193  }
1194
1195  /**
1196   * Divides this measure by a time period and returns the result in the most appropriate unit. This
1197   * is equivalent to {@code div(period.of(1))}.
1198   *
1199   * @param period the time period measurement to divide by.
1200   * @return the division result
1201   */
1202  default Measure<?> per(TimeUnit period) {
1203    return div(period.of(1));
1204  }
1205
1206  /**
1207   * Divides this measure by a torque unit and returns the result in the most appropriate unit. This
1208   * is equivalent to {@code div(divisorUnit.of(1))}.
1209   *
1210   * @param divisorUnit the unit to divide by.
1211   * @return the division result
1212   */
1213  default Measure<?> per(TorqueUnit divisorUnit) {
1214    return div(divisorUnit.one());
1215  }
1216
1217  /**
1218   * Divides this measure by a velocity unit and returns the result in the most appropriate unit.
1219   * This is equivalent to {@code div(divisorUnit.of(1))}.
1220   *
1221   * @param divisorUnit the unit to divide by.
1222   * @return the division result
1223   */
1224  default Measure<?> per(VelocityUnit<?> divisorUnit) {
1225    return div(divisorUnit.one());
1226  }
1227
1228  /**
1229   * Divides this measure by a voltage unit and returns the result in the most appropriate unit.
1230   * This is equivalent to {@code div(divisorUnit.of(1))}.
1231   *
1232   * @param divisorUnit the unit to divide by.
1233   * @return the division result
1234   */
1235  default Measure<?> per(VoltageUnit divisorUnit) {
1236    return div(divisorUnit.one());
1237  }
1238
1239  /**
1240   * Divides this measure by a resistance unit and returns the result in the most appropriate unit.
1241   * This is equivalent to {@code div(divisorUnit.of(1))}.
1242   *
1243   * @param divisorUnit the unit to divide by.
1244   * @return the division result
1245   */
1246  default Measure<?> per(ResistanceUnit divisorUnit) {
1247    return div(divisorUnit.one());
1248  }
1249
1250  /**
1251   * Divides this measure by a ratio in terms of this measurement's unit to another unit, returning
1252   * a measurement in terms of the other unit.
1253   *
1254   * @param divisor the measurement to divide by.
1255   * @param <Other> the other unit that results are in terms of
1256   * @return the division result
1257   */
1258  // eg Dimensionless / (Dimensionless / Time) -> Time
1259  default <Other extends Unit> Measure<Other> divideRatio(
1260      Measure<? extends PerUnit<? extends U, Other>> divisor) {
1261    return ImmutableMeasure.ofBaseUnits(
1262        baseUnitMagnitude() / divisor.baseUnitMagnitude(), divisor.unit().denominator());
1263  }
1264
1265  /**
1266   * Checks if this measure is near another measure of the same unit. Provide a variance threshold
1267   * for use for a +/- scalar, such as 0.05 for +/- 5%.
1268   *
1269   * <pre>
1270   *   Inches.of(11).isNear(Inches.of(10), 0.1) // true
1271   *   Inches.of(12).isNear(Inches.of(10), 0.1) // false
1272   * </pre>
1273   *
1274   * @param other the other measurement to compare against
1275   * @param varianceThreshold the acceptable variance threshold, in terms of an acceptable +/- error
1276   *     range multiplier. Checking if a value is within 10% means a value of 0.1 should be passed;
1277   *     checking if a value is within 1% means a value of 0.01 should be passed, and so on.
1278   * @return true if this unit is near the other measure, otherwise false
1279   */
1280  default boolean isNear(Measure<?> other, double varianceThreshold) {
1281    if (!this.unit().getBaseUnit().equivalent(other.unit().getBaseUnit())) {
1282      return false; // Disjoint units, not compatible
1283    }
1284
1285    // abs so negative inputs are calculated correctly
1286    var tolerance = Math.abs(other.baseUnitMagnitude() * varianceThreshold);
1287
1288    return Math.abs(this.baseUnitMagnitude() - other.baseUnitMagnitude()) <= tolerance;
1289  }
1290
1291  /**
1292   * Checks if this measure is near another measure of the same unit, with a specified tolerance of
1293   * the same unit.
1294   *
1295   * <pre>
1296   *     Meters.of(1).isNear(Meters.of(1.2), Millimeters.of(300)) // true
1297   *     Degrees.of(90).isNear(Rotations.of(0.5), Degrees.of(45)) // false
1298   * </pre>
1299   *
1300   * @param other the other measure to compare against.
1301   * @param tolerance the tolerance allowed in which the two measures are defined as near each
1302   *     other.
1303   * @return true if this unit is near the other measure, otherwise false.
1304   */
1305  default boolean isNear(Measure<U> other, Measure<U> tolerance) {
1306    return Math.abs(this.baseUnitMagnitude() - other.baseUnitMagnitude())
1307        <= Math.abs(tolerance.baseUnitMagnitude());
1308  }
1309
1310  /**
1311   * Checks if this measure is equivalent to another measure of the same unit.
1312   *
1313   * @param other the measure to compare to
1314   * @return true if this measure is equivalent, false otherwise
1315   */
1316  default boolean isEquivalent(Measure<?> other) {
1317    // Return false for disjoint units that aren't compatible
1318    return this.unit().getBaseUnit().equals(other.unit().getBaseUnit())
1319        && Math.abs(baseUnitMagnitude() - other.baseUnitMagnitude()) <= EQUIVALENCE_THRESHOLD;
1320  }
1321
1322  /** {@inheritDoc} */
1323  @Override
1324  default int compareTo(Measure<U> o) {
1325    return Double.compare(this.baseUnitMagnitude(), o.baseUnitMagnitude());
1326  }
1327
1328  /**
1329   * Checks if this measure is greater than another measure of the same unit.
1330   *
1331   * @param o the other measure to compare to
1332   * @return true if this measure has a greater equivalent magnitude, false otherwise
1333   */
1334  default boolean gt(Measure<U> o) {
1335    return compareTo(o) > 0;
1336  }
1337
1338  /**
1339   * Checks if this measure is greater than or equivalent to another measure of the same unit.
1340   *
1341   * @param o the other measure to compare to
1342   * @return true if this measure has an equal or greater equivalent magnitude, false otherwise
1343   */
1344  default boolean gte(Measure<U> o) {
1345    return compareTo(o) > 0 || isEquivalent(o);
1346  }
1347
1348  /**
1349   * Checks if this measure is less than another measure of the same unit.
1350   *
1351   * @param o the other measure to compare to
1352   * @return true if this measure has a lesser equivalent magnitude, false otherwise
1353   */
1354  default boolean lt(Measure<U> o) {
1355    return compareTo(o) < 0;
1356  }
1357
1358  /**
1359   * Checks if this measure is less than or equivalent to another measure of the same unit.
1360   *
1361   * @param o the other measure to compare to
1362   * @return true if this measure has an equal or lesser equivalent magnitude, false otherwise
1363   */
1364  default boolean lte(Measure<U> o) {
1365    return compareTo(o) < 0 || isEquivalent(o);
1366  }
1367
1368  /**
1369   * Returns the measure with the absolute value closest to positive infinity.
1370   *
1371   * @param <U> the type of the units of the measures
1372   * @param measures the set of measures to compare
1373   * @return the measure with the greatest positive magnitude, or null if no measures were provided
1374   */
1375  @SafeVarargs
1376  static <U extends Unit> Measure<U> max(Measure<U>... measures) {
1377    if (measures.length == 0) {
1378      return null; // nothing to compare
1379    }
1380
1381    Measure<U> max = null;
1382    for (Measure<U> measure : measures) {
1383      if (max == null || measure.gt(max)) {
1384        max = measure;
1385      }
1386    }
1387
1388    return max;
1389  }
1390
1391  /**
1392   * Returns the measure with the absolute value closest to negative infinity.
1393   *
1394   * @param <U> the type of the units of the measures
1395   * @param measures the set of measures to compare
1396   * @return the measure with the greatest negative magnitude
1397   */
1398  @SafeVarargs
1399  static <U extends Unit> Measure<U> min(Measure<U>... measures) {
1400    if (measures.length == 0) {
1401      return null; // nothing to compare
1402    }
1403
1404    Measure<U> max = null;
1405    for (Measure<U> measure : measures) {
1406      if (max == null || measure.lt(max)) {
1407        max = measure;
1408      }
1409    }
1410
1411    return max;
1412  }
1413
1414  /**
1415   * Returns a string representation of this measurement in a shorthand form. The symbol of the
1416   * backing unit is used, rather than the full name, and the magnitude is represented in scientific
1417   * notation.
1418   *
1419   * @return the short form representation of this measurement
1420   */
1421  default String toShortString() {
1422    // eg 1.234e+04 V/m (1234 Volt per Meter in long form)
1423    return String.format("%.3e %s", magnitude(), unit().symbol());
1424  }
1425
1426  /**
1427   * Returns a string representation of this measurement in a longhand form. The name of the backing
1428   * unit is used, rather than its symbol, and the magnitude is represented in a full string, not
1429   * scientific notation. (Very large values may be represented in scientific notation, however)
1430   *
1431   * @return the long form representation of this measurement
1432   */
1433  default String toLongString() {
1434    // eg 1234 Volt per Meter (1.234e+04 V/m in short form)
1435    return String.format("%s %s", magnitude(), unit().name());
1436  }
1437}