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