Skip to content

Move qty rounding #315

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased/Snapshot]

### Added
- Added implicit classes for `loactiontec.jts` Geometries that represent geographical geometries with functionality before located in `GeoUtils` [#163] (https://github.com/ie3-institute/PowerSystemUtils/issues/163)
- Added implicit classes for `loactiontec.jts` Geometries that represent geographical geometries with functionality before located in `GeoUtils` [#163](https://github.com/ie3-institute/PowerSystemUtils/issues/163)
- `OsmEntity` and `OsmContainer` to provide a simple, lightweight representation of openstreetmap data
- QuantityUtils previously implemented in SIMONA [#288] (https://github.com/ie3-institute/PowerSystemUtils/issues/288)
- QuantityUtils previously implemented in SIMONA [#288](https://github.com/ie3-institute/PowerSystemUtils/issues/288)

### Changed
- Refactored `GeoUtils`, moved them to the scala package and tailored them toward the `loactiontec.jts` Geometries used in the `OsmContainer` [#163] (https://github.com/ie3-institute/PowerSystemUtils/issues/163)
- Changed unit symbols according to DIN 1301-1 for apparent and reactive power [#278] (https://github.com/ie3-institute/PowerSystemUtils/issues/278)
- Refactored `GeoUtils`, moved them to the scala package and tailored them toward the `loactiontec.jts` Geometries used in the `OsmContainer` [#163](https://github.com/ie3-institute/PowerSystemUtils/issues/163)
- Changed unit symbols according to DIN 1301-1 for apparent and reactive power [#278](https://github.com/ie3-institute/PowerSystemUtils/issues/278)
- Rounding for quantities is now part of the `RichQuantity` [#314](https://github.com/ie3-institute/PowerSystemUtils/issues/314)

### Fixed
- Fix tests in CI [#206](https://github.com/ie3-institute/PowerSystemUtils/issues/206)
Expand Down
57 changes: 27 additions & 30 deletions src/main/scala/edu/ie3/util/quantities/QuantityUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,36 +46,6 @@ import scala.math.BigDecimal.RoundingMode.RoundingMode

object QuantityUtils {

/** Rounds a quantity given a specified rounding mode after a specified
* decimal.
*
* @param quantity
* the quantity to round
* @param decimals
* how many decimals to consider
* @param roundingMode
* the rounding mode to use
* @tparam T
* type of the quantity
* @return
* the rounded quantity
*/
def round[T <: Quantity[T]](
quantity: ComparableQuantity[T],
decimals: Int,
roundingMode: RoundingMode = RoundingMode.HALF_UP
): ComparableQuantity[T] = {
if (decimals < 0)
throw new IllegalArgumentException(
"You can not round to negative decimal places."
)
val rounded = BigDecimal
.valueOf(quantity.getValue.doubleValue())
.setScale(decimals, roundingMode)
.doubleValue
Quantities.getQuantity(rounded, quantity.getUnit)
}

/** Implicit class to enrich the [[Double]] with [[ComparableQuantity]]
* conversion capabilities
*
Expand Down Expand Up @@ -281,6 +251,33 @@ object QuantityUtils {
def max(other: ComparableQuantity[Q]): ComparableQuantity[Q] = {
if (q.isGreaterThan(other)) q else other
}

/** Rounds a quantity given a specified rounding mode after a specified
* decimal.
*
* @param decimals
* how many decimals to consider
* @param roundingMode
* the rounding mode to use
* @tparam Q
* type of the quantity
* @return
* the rounded quantity
*/
def round(
decimals: Int,
roundingMode: RoundingMode = RoundingMode.HALF_UP
): ComparableQuantity[Q] = {
if (decimals < 0)
throw new IllegalArgumentException(
"You can not round to negative decimal places."
)
val rounded = BigDecimal
.valueOf(q.getValue.doubleValue())
.setScale(decimals, roundingMode)
.doubleValue
Quantities.getQuantity(rounded, q.getUnit)
}
}

implicit class RichUnit[Q <: Quantity[Q]](
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import edu.ie3.util.quantities.QuantityMatchers.equalWithTolerance
import edu.ie3.util.quantities.QuantityUtils.{
RichQuantity,
RichQuantityDouble,
RichUnit,
round
RichUnit
}
import org.scalatest.matchers.should.Matchers
import org.scalatest.prop.TableDrivenPropertyChecks
Expand All @@ -33,12 +32,12 @@ class QuantityUtilsSpec
val qty = 10.1245.asAmpere

"round a quantity half up by default" in {
round(qty, 2) should equalWithTolerance(10.12.asAmpere)
round(qty, 3) should equalWithTolerance(10.125.asAmpere)
qty.round(2) should equalWithTolerance(10.12.asAmpere)
qty.round(3) should equalWithTolerance(10.125.asAmpere)
}

"round a quantity with the given rounding mode" in {
round(qty, 3, RoundingMode.HALF_DOWN) should equalWithTolerance(
qty.round(3, RoundingMode.HALF_DOWN) should equalWithTolerance(
10.124.asAmpere
)
}
Expand Down