Skip to content
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

[5xx] Payal Khanna Added function RoundToSignificantFigure #3180

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
38 changes: 38 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
# *CDM Model - RoundToSignificantFigures Function*

_Background_

This release contains a new function for `RoundToSignificantFigures` function, as described in issue [#3154](https://github.com/finos/common-domain-model/issues/3154).

_What is being released?_

This release creates the new function `cdm.base.math.RoundToSignificantFigures` to round to the significant number of decimal places.

```
func RoundToSignificantFigures: <"Round a number to the supplied significant figures, using the supplied rounding direction.">
inputs:
value number (1..1) <"The original (unrounded) number.">
significantFigures int (1..1) <"The number of significant figures.">
roundingMode RoundingDirectionEnum (1..1) <"The method of rounding (up/down/nearest).">
output:
roundedValue number (1..1) <"The value to the desired number of significant figures.">

condition NonZeroSignificantFigures: <"The number of significant figures should be greater than zero.">
significantFigures > 0
```

The following examples show the function behaviour:
- `RoundToSignificantFigures(1023.123456789, 5, RoundingDirectionEnum -> NEAREST)` = 1023.1
- `RoundToSignificantFigures(1023.123456789, 5, RoundingDirectionEnum -> UP)` = 1023.2
- `RoundToSignificantFigures(1023.123456789, 5, RoundingDirectionEnum -> DOWN)` = 1023.1
- `RoundToSignificantFigures(1023.123456789, 1, RoundingDirectionEnum -> NEAREST)` = 1000
- `RoundToSignificantFigures(1023.1, 7, RoundingDirectionEnum -> NEAREST)` = 1023.1

This would be a new function, so there would be no compatibility issues.

_Review Directions_

In Rosetta, select the Textual Browser and inspect the changes identified above.

Changes can be reviewed in PR [#3180](https://github.com/finos/common-domain-model/pull/3180)

# _Infrastructure - Dependency Update_

_What is being released?_
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package cdm.base.math.functions;

import cdm.base.math.RoundingDirectionEnum;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;

public class RoundToSignificantFiguresImpl extends RoundToSignificantFigures {

// round a supplied value to the specified significant figures
@Override
protected BigDecimal doEvaluate(BigDecimal value, Integer significantFigures, RoundingDirectionEnum roundingMode) {
if (value == null) return null;
if (significantFigures == null || roundingMode == null) return value;

return value.round(new MathContext(significantFigures, toRoundingMode(roundingMode)));
}

private RoundingMode toRoundingMode(RoundingDirectionEnum roundingMode) {
switch (roundingMode) {
case UP:
return RoundingMode.UP;
case DOWN:
return RoundingMode.DOWN;
case NEAREST:
return RoundingMode.HALF_UP;
default:
throw new IllegalArgumentException("Unsupported RoundingDirectionEnum " + roundingMode);
}
}
}
11 changes: 11 additions & 0 deletions rosetta-source/src/main/rosetta/base-math-func.rosetta
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,17 @@ func RoundToPrecision: <"Round a number to the supplied precision, using the sup
condition NonNegativePrecision:
precision >= 0

func RoundToSignificantFigures: <"Round a number to the supplied significant figures, using the supplied rounding direction.">
inputs:
value number (1..1) <"The original (unrounded) number.">
significantFigures int (1..1) <"The number of significant figures.">
roundingMode RoundingDirectionEnum (1..1) <"The method of rounding (up/down/nearest).">
output:
roundedValue number (1..1) <"The value to the desired number of significant figures.">

condition NonZeroSignificantFigures: <"The number of significant figures should be greater than zero.">
significantFigures > 0

func CompareQuantityByUnitOfAmount:
inputs:
quantity1 Quantity (0..*)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package cdm.base.math.functions;

import cdm.base.math.RoundingDirectionEnum;
import org.junit.jupiter.api.Test;

import java.math.BigDecimal;

import static org.junit.jupiter.api.Assertions.assertEquals;

class RoundToSignificantFiguresImplTest {

@Test
void shouldRoundToNearest5SignificantFigures() {
RoundToSignificantFiguresImpl func = new RoundToSignificantFiguresImpl();
BigDecimal result = func.doEvaluate(BigDecimal.valueOf(1023.123456789), 5, RoundingDirectionEnum.NEAREST);
assertEquals("1023.1", result.toPlainString());
}

@Test
void shouldRoundUpTo5SignificantFigures() {
RoundToSignificantFiguresImpl func = new RoundToSignificantFiguresImpl();
BigDecimal result = func.doEvaluate(BigDecimal.valueOf(1023.123456789), 5, RoundingDirectionEnum.UP);
assertEquals("1023.2", result.toPlainString());
}

@Test
void shouldRoundDownTo5SignificantFigures() {
RoundToSignificantFiguresImpl func = new RoundToSignificantFiguresImpl();
BigDecimal result = func.doEvaluate(BigDecimal.valueOf(1023.123456789), 5, RoundingDirectionEnum.DOWN);
assertEquals("1023.1", result.toPlainString());
}

@Test
void shouldRoundToNearest1SignificantFigures() {
RoundToSignificantFiguresImpl func = new RoundToSignificantFiguresImpl();
BigDecimal result = func.doEvaluate(BigDecimal.valueOf(1023.123456789), 1, RoundingDirectionEnum.NEAREST);
assertEquals("1000", result.toPlainString());
}

@Test
void shouldRoundToNearest7SignificantFigures() {
RoundToSignificantFiguresImpl func = new RoundToSignificantFiguresImpl();
BigDecimal result = func.doEvaluate(BigDecimal.valueOf(1023.1), 7, RoundingDirectionEnum.NEAREST);
assertEquals("1023.1", result.toPlainString());
}
}
Loading