> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dairy.foundation/llms.txt
> Use this file to discover all available pages before exploring further.

# Distances

First we'll look at `Distance`. `Distance` and `Current` are super similar, they
just have different families, so there's no point in looking at both of them.

<CodeGroup>
  ```java Java theme={null}
  // both of these methods work for constructing a new Distance!
  Distance tenMM = new Distance(DistanceUnits.MILLIMETER, 10.0);
  // OR
  Distances.mm(10);
  ```

  ```kt Kotlin theme={null}
  // both of these methods work for constructing a new Distance!
  val tenMM = Distance(DistanceUnits.MILLIMETER, 10.0)
  // OR
  10.mm // wow, cool, an extension function!
  ```
</CodeGroup>

We can get the actual value of the current as so:

<CodeGroup>
  ```java Java theme={null}
  tenMM.getValue(); // double
  ```

  ```kt Kotlin theme={null}
  tenMM.value // Double
  ```
</CodeGroup>

And if we want to get the unit that was provided:

<CodeGroup>
  ```java Java theme={null}
  tenMM.getUnit(); // DistanceUnit
  ```

  ```kt Kotlin theme={null}
  tenMM.unit // DistanceUnit
  ```
</CodeGroup>

We can convert between the units in two different ways:

<CodeGroup>
  ```java Java theme={null}
  // this is a no-op, so its free
  Distance asMillimeters = tenMM.into(DistanceUnits.MILLIMETER);
  Distance asCentimeters = tenMM.into(DistanceUnits.CENTIMETER);
  Distance asMeters = tenMM.into(DistanceUnits.METER);

  Distance asInches = tenMM.into(DistanceUnits.INCH);
  Distance asFeet = tenMM.into(DistanceUnits.FEET);

  // OR

  // quick conversions for "batteries included" units
  // still a no-op
  tenMM.intoMillimeters();
  tenMM.intoCentimeters();
  tenMM.intoMeters();

  tenMM.intoInches();
  tenMM.intoFeet();

  // if you define your own units, these quick conversion methods won't exist,
  // sorry!
  ```

  ```kt Kotlin theme={null}
  // this is a no-op, so its free
  val asMillimeters: Distance = tenMM.into(DistanceUnits.MILLIMETER)
  val asCentimeters: Distance = tenMM.into(DistanceUnits.CENTIMETER)
  val asMeters: Distance = tenMM.into(DistanceUnits.METER)

  val asInches: Distance = tenMM.into(DistanceUnits.INCH)
  val asFeet: Distance = tenMM.into(DistanceUnits.FEET)

  // OR

  // quick conversions for "batteries included" units
  tenMM.intoMillimeters()
  tenMM.intoCentimeters()
  tenMM.intoMeters()

  tenMM.intoInches()
  tenMM.intoFeet()

  // if you define your own units, these quick conversion methods won't exist,
  // sorry!
  ```
</CodeGroup>

All expected mathematical operations are defined:

<CodeGroup>
  ```java Java theme={null}
  tenMM.plus(asInches);
  tenMM.minus(asInches);
  tenMM.times(asInches);
  tenMM.div(asInches);

  // just doubles also works for times and divide
  tenMM.times(10);
  tenMM.div(10);

  // the inverse (-tenMM)
  tenMM.unaryMinus();
  // this is a no-op (+tenMM)
  tenMM.unaryPlus();

  // the sign of the value (-1.0, 0.0, 1.0)
  tenMM.getSign();
  // the absolute value
  tenMM.getAbsoluteValue();

  // if the stored value is Double.NaN
  tenMM.isNaN();

  // unit specific error calculation (behaves differently for `Angle`s)
  tenMM.findError(asInches);

  // modulo (%)
  // note that there is also rem, which is the same
  tenMM.mod(asInches);
  tenMM.mod(10);

  // gets the value of this when converted to the supplied unit
  // returns a double, not a new Distance
  tenMM.get(DistanceUnits.INCH);

  // coerce's the unit to be in these bounds
  tenMM.coerceAtLeast(asInches);
  tenMM.coerceAtMost(asInches);
  tenMM.coerceIn(asInches, asInches);
  ```

  ```kt Kotlin theme={null}
  tenMM + asInches
  tenMM - asInches
  tenMM * asInches
  tenMM / asInches

  // just doubles also works for times and divide
  tenMM * 10.0
  tenMM / 10.0

  // the inverse
  -tenMM
  // this is a no-op
  +tenMM

  // the sign of the value (-1.0, 0.0, 1.0)
  tenMM.sign
  // the absolute value
  tenMM.absoluteValue

  // if the stored value is Double.NaN
  tenMM.isNaN()

  // unit specific error calculation (behaves differently for `Angle`s)
  tenMM.findError(asInches)

  // remainder (rem)
  // note that there is also mod, which is the same
  tenMM % asInches
  tenMM % 10

  // gets the value of this when converted to the supplied unit
  // returns a double, not a new Distance
  tenMM[DistanceUnits.INCH]

  // coerce's the unit to be in these bounds
  tenMM.coerceAtLeast(asInches)
  tenMM.coerceAtMost(asInches)
  tenMM.coerceIn(asInches, asInches)
  ```
</CodeGroup>

Note that all of these operations are non-mutating, the value of `tenMM` never
changes, instead, you need to store the results of the operations, and use the
new output instead.

These operations are also written to avoid making allocation where possible,
which means, where possible, `tenMM` will be returned, rather than a new
`Distance`.

Finally, all operations involving more than one `ReifiedUnit` value, result in a
`ReifiedUnit` with a `unit` of the left hand side, so if you chain a whole bunch
of operations on a `Distance` with `unit` `DistanceUnits.METER`, then the result
should also have `unit` `DistanceUnits.METER`.

Comparisons are also defined:

<CodeGroup>
  ```java Java theme={null}
  tenMM.lessThan(asInches);
  tenMM.lessThanEqualTo(asInches);
  tenMM.greaterThan(asInches);
  tenMM.greaterThanEqualTo(asInches);
  ```

  ```kt Kotlin theme={null}
  tenMM < asInches
  tenMM <= asInches
  tenMM > asInches
  tenMM >= asInches
  ```
</CodeGroup>
