typelevel / squants

The Scala API for Quantities, Units of Measure and Dimensional Analysis
https://www.squants.com
Apache License 2.0
922 stars 122 forks source link

inBestUnit #443

Open Lasering opened 3 years ago

Lasering commented 3 years ago

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

Lasering commented 2 years ago

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)
Lasering commented 1 year ago

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