typelevel/squants

inBestUnit

Opened this issue · 2 comments

Quantity could have a method toCoarsest like the one in Duration.

Return duration which is equal to this duration but with a coarsest Unit, or self in case it is already the coarsest Unit

Examples:

Duration(60, MINUTES).toCoarsest // Duration(1, HOURS)
Duration(1000, MILLISECONDS).toCoarsest // Duration(1, SECONDS)
Duration(48, HOURS).toCoarsest // Duration(2, DAYS)
Duration(5, SECONDS).toCoarsest // Duration(5, SECONDS)

But since quantities are doubles the toCoarsest would also do:

import squants.information.Information
import squants.information.InformationConversions._

900.gibibytes.toCoarsest // 0.9 Tebibytes

Why? Because to show information to an user the later is more user friendly

A very similar thing used to exist in DefaultFormatter. Adapted it to work with the latest Squants version:

given [Q <: Quantity[Q]]: Ordering[UnitOfMeasure[Q]] = (x: UnitOfMeasure[Q], y: UnitOfMeasure[Q]) =>
  val siUnit = x(1).dimension.siUnit
  val xSI = x(1).to(siUnit)
  val ySI = y(1).to(siUnit)
  xSI.compare(ySI)

extension [Q <: Quantity[Q]](quantity: Quantity[Q])
  def inBestUnit(units: TreeSet[UnitOfMeasure[Q]] = quantity.dimension.units.to(TreeSet)): Q =
    val unit = units
      .takeWhile { u => quantity.to(u).abs >= 1.0 }
      .lastOption
      .getOrElse(units.head)
    quantity.in(unit)

In this something that would be merged? I can do a PR.