Skip to content

Commit

Permalink
Implement Area.times(Length) and Length.times(Area)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevincianfarini committed Dec 31, 2024
1 parent c0232c5 commit 542a324
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,40 @@ public value class Area internal constructor(private val rawMillimetersSquared:
* @throws IllegalArgumentException if this area is [infinite][isInfinite] and [length] is zero, or if this area
* is zero and [length] is infinite.
*/
public operator fun times(length: Length): Volume = TODO()
public operator fun times(length: Length): Volume {
return length.toInternationalComponents { giga, mega, kilo, meters, centi, milli, micro, nano ->
// Try to find the right level which we can perform this operation at without losing precision.
// --------------------------------------------------------------------------------------------
// 1 millimeter² * 1 nm is 1 picoliter.
// 1 millimeter² * 1 μm is 1 nanoliter.
// 1 millimeter² * 1 mm is 1 microliter.
// 1 millimeter² * 1 cm is 10 microliters.
// 1 millimeter² * 1 m is 1 milliliter.
// 1 millimeter² * 1 km is 1 liter.
// 1 millimeter² * 1 Mm is 1 kiloliter.
// 1 millimeter² * 1 Gm is 1 megaliter.
// --------------------------------------------------------------------------------------------
val megaliters = rawMillimetersSquared * giga
val kiloliters = rawMillimetersSquared * mega
val liters = rawMillimetersSquared * kilo
val milliliters = rawMillimetersSquared * meters
val microliters = (rawMillimetersSquared * centi * 10) + (rawMillimetersSquared * milli)
val nanoliters = rawMillimetersSquared * micro
val picoliters = rawMillimetersSquared * nano
// ----------- Try picoliter precision. ------------------------------------------------------
val picoL = picoliters + (nanoliters * 1_000) + (microliters * 1_000_000) + (milliliters * 1_000_000_000) + (liters * 1_000_000_000_000) + (kiloliters * 1_000_000_000_000_000) + (megaliters * 1_000_000_000_000_000_000)
if (picoL.isFinite()) return@toInternationalComponents Volume(picoL / 1_000_000_000)
// ----------- Try nanoliter precision. ------------------------------------------------------
val nanoL = (picoliters / 1_000) + nanoliters + (microliters * 1_000) + (milliliters * 1_000_000) + (liters * 1_000_000_000) + (kiloliters * 1_000_000_000_000) + (megaliters * 1_000_000_000_000_000)
if (nanoL.isFinite()) return@toInternationalComponents Volume(nanoL / 1_000_000)
// ----------- Try microliter precision. -----------------------------------------------------
val microL = (picoliters / 1_000_000) + (nanoliters / 1_000) + microliters + (milliliters * 1_000) + (liters * 1_000_000) + (kiloliters * 1_000_000_000) + (megaliters * 1_000_000_000_000)
if (microL.isFinite()) return@toInternationalComponents Volume(microL / 1_000)
// ----------- Default milliliter precision. -------------------------------------------------
val milliL = (picoliters / 1_000_000_000) + (nanoliters / 1_000_000) + (microliters / 1_000) + milliliters + (liters * 1_000) + (kiloliters * 1_000_000) + (megaliters * 1_000_000_000)
Volume(milliL)
}
}

// endregion

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,17 @@ public value class Length internal constructor(internal val rawNanometers: Satur
}
}

/**
* Returns the resulting [Volume] after applying this length over the specified [area].
*
* This operation attempts to retain precision, but for sufficiently large values of this length or the
* specified [area] some precision may be lost.
*
* @throws IllegalArgumentException if this length is [infinite][isInfinite] and [area] is zero, or if this length
* is zero and [area] is infinite.
*/
public operator fun times(area: Area): Volume = area * this

/**
* Returns the amount of [Energy] required to apply the specified [force] over this length.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package io.github.kevincianfarini.alchemist
import io.github.kevincianfarini.alchemist.internal.NEGATIVE_INFINITY
import io.github.kevincianfarini.alchemist.internal.POSITIVE_INFINITY
import io.github.kevincianfarini.alchemist.scalar.kilometers
import io.github.kevincianfarini.alchemist.scalar.liters
import io.github.kevincianfarini.alchemist.scalar.meters
import io.github.kevincianfarini.alchemist.scalar.milliliters
import io.github.kevincianfarini.alchemist.scalar.millimeters
import io.github.kevincianfarini.alchemist.scalar.mm2
import io.github.kevincianfarini.alchemist.scalar.nanometers
Expand Down Expand Up @@ -205,4 +208,12 @@ class AreaTest {
assertFalse(POSITIVE_INFINITY.mm2.isFinite())
assertFalse(NEGATIVE_INFINITY.mm2.isFinite())
}

@Test
fun area_mul_length_simple() {
assertEquals(
expected = 1_219_251.milliliters,
actual = 123_456_000_000.mm2 * 9_876.nanometers,
)
}
}

0 comments on commit 542a324

Please sign in to comment.