11package io .github .qudtlib .model ;
22
33import static io .github .qudtlib .nodedef .Builder .buildSet ;
4+ import static java .math .BigDecimal .ONE ;
45
56import io .github .qudtlib .exception .InconvertibleQuantitiesException ;
67import io .github .qudtlib .nodedef .Builder ;
@@ -395,16 +396,21 @@ public BigDecimal convert(BigDecimal value, Unit toUnit, QuantityKind quantityKi
395396 }
396397 BigDecimal fromOffset =
397398 ignoreOffset ? BigDecimal .ZERO : this .getConversionOffset ().orElse (BigDecimal .ZERO );
398- BigDecimal fromMultiplier = this .getConversionMultiplier ().orElse (BigDecimal . ONE );
399+ BigDecimal fromMultiplier = this .getConversionMultiplier ().orElse (ONE );
399400 BigDecimal toOffset =
400401 ignoreOffset
401402 ? BigDecimal .ZERO
402403 : toUnit .getConversionOffset ().orElse (BigDecimal .ZERO );
403- BigDecimal toMultiplier = toUnit .getConversionMultiplier ().orElse (BigDecimal .ONE );
404- return value .add (fromOffset )
405- .multiply (fromMultiplier , MathContext .DECIMAL128 )
406- .divide (toMultiplier , MathContext .DECIMAL128 )
407- .subtract (toOffset );
404+ BigDecimal toMultiplier = toUnit .getConversionMultiplier ().orElse (ONE );
405+ BigDecimal result =
406+ value .add (fromOffset )
407+ .multiply (fromMultiplier , MathContext .DECIMAL128 )
408+ .divide (toMultiplier , MathContext .DECIMAL128 )
409+ .subtract (toOffset );
410+ int resultPrecision = Math .min (BigDecimal .ONE .equals (value ) ? 3 : value .precision (), 34 );
411+
412+ MathContext resultContext = new MathContext (resultPrecision );
413+ return result .round (resultContext );
408414 }
409415
410416 /**
@@ -417,7 +423,7 @@ public BigDecimal convert(BigDecimal value, Unit toUnit, QuantityKind quantityKi
417423 */
418424 public BigDecimal getConversionMultiplier (Unit toUnit ) {
419425 if (this .equals (toUnit )) {
420- return BigDecimal . ONE ;
426+ return ONE ;
421427 }
422428 if (this .conversionOffsetDiffers (toUnit )) {
423429 throw new IllegalArgumentException (
@@ -427,25 +433,31 @@ public BigDecimal getConversionMultiplier(Unit toUnit) {
427433 }
428434 Optional <BigDecimal > fromMultiplier = this .getConversionMultiplier ();
429435 Optional <BigDecimal > toMultiplier = toUnit .getConversionMultiplier ();
430- return fromMultiplier
431- .map (
432- from ->
433- toMultiplier
434- .map (to -> from .divide (to , MathContext .DECIMAL128 ))
435- .orElse (null ))
436- .orElseThrow (
437- () ->
438- new InconvertibleQuantitiesException (
439- String .format (
440- "Cannot convert %s(%s) to %s(%s)" ,
441- this .getIriAbbreviated (),
442- this .getConversionMultiplier ().isEmpty ()
443- ? "no multiplier"
444- : "has multiplier" ,
445- toUnit .getIriAbbreviated (),
446- toUnit .getConversionMultiplier ().isEmpty ()
447- ? "no multiplier"
448- : "has multiplier" )));
436+ BigDecimal result =
437+ fromMultiplier
438+ .map (
439+ from ->
440+ toMultiplier
441+ .map (to -> from .divide (to , MathContext .DECIMAL128 ))
442+ .orElse (null ))
443+ .orElseThrow (
444+ () ->
445+ new InconvertibleQuantitiesException (
446+ String .format (
447+ "Cannot convert %s(%s) to %s(%s)" ,
448+ this .getIriAbbreviated (),
449+ this .getConversionMultiplier ().isEmpty ()
450+ ? "no multiplier"
451+ : "has multiplier" ,
452+ toUnit .getIriAbbreviated (),
453+ toUnit .getConversionMultiplier ().isEmpty ()
454+ ? "no multiplier"
455+ : "has multiplier" )));
456+ int precision = Math .min (34 , result .precision ());
457+ return result .round (
458+ new MathContext (
459+ precision )); // TODO: when units know about their precision we can improve
460+ // this
449461 }
450462
451463 public boolean conversionOffsetDiffers (Unit other ) {
0 commit comments