From a7a13ab616f797f9888e55c8fe62cf8800cf3b45 Mon Sep 17 00:00:00 2001 From: Florian Kleedorfer Date: Fri, 25 Jul 2025 14:45:45 +0200 Subject: [PATCH 1/2] Strip trailing zeros resulting from unit conversion --- CHANGELOG.md | 4 ++ .../java/io/github/qudtlib/model/Unit.java | 43 ++++++++++--------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cdcd882..96d7bb1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- `Unit.convert()` and `Unit.getConversionMultiplier(Unit)` now strip any trailing fractional zeros. + ## [7.0.0] - 2025-07-22 ### Added diff --git a/qudtlib-model/src/main/java/io/github/qudtlib/model/Unit.java b/qudtlib-model/src/main/java/io/github/qudtlib/model/Unit.java index 0b04908b..1a128f32 100644 --- a/qudtlib-model/src/main/java/io/github/qudtlib/model/Unit.java +++ b/qudtlib-model/src/main/java/io/github/qudtlib/model/Unit.java @@ -404,7 +404,8 @@ public BigDecimal convert(BigDecimal value, Unit toUnit, QuantityKind quantityKi return value.add(fromOffset) .multiply(fromMultiplier, MathContext.DECIMAL128) .divide(toMultiplier, MathContext.DECIMAL128) - .subtract(toOffset); + .subtract(toOffset) + .stripTrailingZeros(); } /** @@ -427,25 +428,27 @@ public BigDecimal getConversionMultiplier(Unit toUnit) { } Optional fromMultiplier = this.getConversionMultiplier(); Optional toMultiplier = toUnit.getConversionMultiplier(); - return fromMultiplier - .map( - from -> - toMultiplier - .map(to -> from.divide(to, MathContext.DECIMAL128)) - .orElse(null)) - .orElseThrow( - () -> - new InconvertibleQuantitiesException( - String.format( - "Cannot convert %s(%s) to %s(%s)", - this.getIriAbbreviated(), - this.getConversionMultiplier().isEmpty() - ? "no multiplier" - : "has multiplier", - toUnit.getIriAbbreviated(), - toUnit.getConversionMultiplier().isEmpty() - ? "no multiplier" - : "has multiplier"))); + BigDecimal result = + fromMultiplier + .map( + from -> + toMultiplier + .map(to -> from.divide(to, MathContext.DECIMAL128)) + .orElse(null)) + .orElseThrow( + () -> + new InconvertibleQuantitiesException( + String.format( + "Cannot convert %s(%s) to %s(%s)", + this.getIriAbbreviated(), + this.getConversionMultiplier().isEmpty() + ? "no multiplier" + : "has multiplier", + toUnit.getIriAbbreviated(), + toUnit.getConversionMultiplier().isEmpty() + ? "no multiplier" + : "has multiplier"))); + return result.stripTrailingZeros(); } public boolean conversionOffsetDiffers(Unit other) { From 6970666815a939f3dde680f7cc17ed88c58280c6 Mon Sep 17 00:00:00 2001 From: Florian Kleedorfer Date: Fri, 25 Jul 2025 15:20:45 +0200 Subject: [PATCH 2/2] Ensure scale >= 0 in conversion results --- CHANGELOG.md | 3 ++- .../java/io/github/qudtlib/model/Unit.java | 21 +++++++++++++------ .../java/io/github/qudtlib/QudtTests.java | 8 ++++--- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96d7bb1d..3c675f6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- `Unit.convert()` and `Unit.getConversionMultiplier(Unit)` now strip any trailing fractional zeros. +- `Unit.convert()` and `Unit.getConversionMultiplier(Unit)` now strip any trailing fractional zeros and the + scale of the result is >= 0. ## [7.0.0] - 2025-07-22 diff --git a/qudtlib-model/src/main/java/io/github/qudtlib/model/Unit.java b/qudtlib-model/src/main/java/io/github/qudtlib/model/Unit.java index 1a128f32..b131e8bc 100644 --- a/qudtlib-model/src/main/java/io/github/qudtlib/model/Unit.java +++ b/qudtlib-model/src/main/java/io/github/qudtlib/model/Unit.java @@ -401,11 +401,16 @@ public BigDecimal convert(BigDecimal value, Unit toUnit, QuantityKind quantityKi ? BigDecimal.ZERO : toUnit.getConversionOffset().orElse(BigDecimal.ZERO); BigDecimal toMultiplier = toUnit.getConversionMultiplier().orElse(BigDecimal.ONE); - return value.add(fromOffset) - .multiply(fromMultiplier, MathContext.DECIMAL128) - .divide(toMultiplier, MathContext.DECIMAL128) - .subtract(toOffset) - .stripTrailingZeros(); + BigDecimal result = + value.add(fromOffset) + .multiply(fromMultiplier, MathContext.DECIMAL128) + .divide(toMultiplier, MathContext.DECIMAL128) + .subtract(toOffset) + .stripTrailingZeros(); + if (result.scale() < 0) { + result = result.setScale(0); + } + return result; } /** @@ -448,7 +453,11 @@ public BigDecimal getConversionMultiplier(Unit toUnit) { toUnit.getConversionMultiplier().isEmpty() ? "no multiplier" : "has multiplier"))); - return result.stripTrailingZeros(); + result = result.stripTrailingZeros(); + if (result.scale() < 0) { + result = result.setScale(0); + } + return result; } public boolean conversionOffsetDiffers(Unit other) { diff --git a/qudtlib-test/src/test/java/io/github/qudtlib/QudtTests.java b/qudtlib-test/src/test/java/io/github/qudtlib/QudtTests.java index 1a8ef19d..061b66d1 100644 --- a/qudtlib-test/src/test/java/io/github/qudtlib/QudtTests.java +++ b/qudtlib-test/src/test/java/io/github/qudtlib/QudtTests.java @@ -569,10 +569,12 @@ public void testMilliSV__PER__HR_to_MicroSV__PER__HR() { u.getIriLocalname(), u.getConversionMultiplier().get().toString()))); */ - MatcherAssert.assertThat( + BigDecimal converted = Qudt.convert( - new BigDecimal("15.12"), Units.MilliSV__PER__HR, Units.MicroSV__PER__HR), - Matchers.comparesEqualTo(new BigDecimal(15120))); + new BigDecimal("15.12"), Units.MilliSV__PER__HR, Units.MicroSV__PER__HR); + MatcherAssert.assertThat(converted, Matchers.comparesEqualTo(new BigDecimal(15120))); + BigDecimal expected = new BigDecimal(15120); + assertEquals(expected, converted); } @Test