Skip to content
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: 8 additions & 1 deletion src/decimojo/__init__.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,14 @@ from .decimal.decimal import Decimal, Dec
from .bigint.bigint import BigInt, BInt
from .biguint.biguint import BigUInt, BUInt
from .bigdecimal.bigdecimal import BigDecimal, BigDec, BDec
from .rounding_mode import RoundingMode, RM
from .rounding_mode import (
RoundingMode,
RM,
ROUND_DOWN,
ROUND_HALF_UP,
ROUND_HALF_EVEN,
ROUND_UP,
)

# Core functions
from .decimal.arithmetics import (
Expand Down
27 changes: 24 additions & 3 deletions src/decimojo/bigdecimal/bigdecimal.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -739,9 +739,30 @@ struct BigDecimal(
return decimojo.bigdecimal.exponential.power(self, exponent, precision)

@always_inline
fn round(self, ndigits: Int, rounding_mode: RoundingMode) raises -> Self:
"""Rounds the number to the specified precision.
See `bigdecimal.rounding.round()` for more information.
fn round(
self,
ndigits: Int,
rounding_mode: RoundingMode = RoundingMode.ROUND_HALF_EVEN,
) raises -> Self:
"""Rounds the number to the specified number of decimal places.

Args:
ndigits: Number of decimal places to round to.
rounding_mode: Rounding mode to use. Default is `ROUND_HALF_EVEN`.
RoundingMode.ROUND_DOWN: Round down.
RoundingMode.ROUND_UP: Round up.
RoundingMode.ROUND_HALF_UP: Round half up.
RoundingMode.ROUND_HALF_EVEN: Round half even.

Notes:
If `ndigits` is negative, the last `ndigits` digits of the integer part of
the number will be dropped and the scale will be `ndigits`.
Examples:
round(123.456, 2) -> 123.46
round(123.456, -1) -> 12E+1
round(123.456, -2) -> 1E+2
round(123.456, -3) -> 0E+3
round(678.890, -3) -> 1E+3
"""
return decimojo.bigdecimal.rounding.round(self, ndigits, rounding_mode)

Expand Down
17 changes: 8 additions & 9 deletions src/decimojo/bigdecimal/rounding.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,14 @@ fn round(
RoundingMode.ROUND_HALF_EVEN: Round half even.

Notes:

If `ndigits` is negative, the last `ndigits` digits of the integer part of
the number will be dropped and the scale will be `ndigits`.
Example:
round(123.456, 2) -> 123.46
round(123.456, -1) -> 12E+1
round(123.456, -2) -> 1E+2
round(123.456, -3) -> 0E+3
round(678.890, -3) -> 1E+3
If `ndigits` is negative, the last `ndigits` digits of the integer part of
the number will be dropped and the scale will be `ndigits`.
Examples:
round(123.456, 2) -> 123.46
round(123.456, -1) -> 12E+1
round(123.456, -2) -> 1E+2
round(123.456, -3) -> 0E+3
round(678.890, -3) -> 1E+3
"""
var ndigits_to_remove = number.scale - ndigits
if ndigits_to_remove == 0:
Expand Down
9 changes: 8 additions & 1 deletion src/decimojo/prelude.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,11 @@ from decimojo.decimal.decimal import Decimal, Dec
from decimojo.bigdecimal.bigdecimal import BigDecimal, BDec
from decimojo.biguint.biguint import BigUInt, BUInt
from decimojo.bigint.bigint import BigInt, BInt
from decimojo.rounding_mode import RoundingMode, RM
from decimojo.rounding_mode import (
RoundingMode,
RM,
ROUND_DOWN,
ROUND_HALF_UP,
ROUND_HALF_EVEN,
ROUND_UP,
)
4 changes: 4 additions & 0 deletions src/decimojo/rounding_mode.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
"""

alias RM = RoundingMode
alias ROUND_DOWN = RoundingMode.ROUND_DOWN
alias ROUND_HALF_UP = RoundingMode.ROUND_HALF_UP
alias ROUND_HALF_EVEN = RoundingMode.ROUND_HALF_EVEN
alias ROUND_UP = RoundingMode.ROUND_UP


struct RoundingMode(Stringable):
Expand Down
34 changes: 10 additions & 24 deletions src/decimojo/tests.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -79,32 +79,18 @@ struct TestCase(Copyable, Movable, Stringable, Writable):
writer.write(" description: " + self.description + "\n")


fn load_test_cases(
file_path: String, table_name: String, has_expected_value: Bool = True
) raises -> List[TestCase]:
"""Load test cases from a TOML file for a specific table."""
var toml = tomlmojo.parse_file(file_path)
var test_cases = List[TestCase]()

# Get array of test cases
var cases_array = toml.get_array_of_tables(table_name)

for i in range(len(cases_array)):
var case_table = cases_array[i]
var expected_value = case_table[
"expected"
].as_string() if has_expected_value else String("")
test_cases.append(
TestCase(
case_table["a"].as_string(),
case_table["b"].as_string(),
expected_value,
case_table["description"].as_string(),
)
fn parse_file(file_path: String) raises -> tomlmojo.parser.TOMLDocument:
"""Parse a TOML file and return the TOMLDocument."""
try:
return tomlmojo.parse_file(file_path)
except e:
raise Error(
"tests.parse_file(): Failed to parse TOML file:",
file_path,
"\nTraceback:",
e,
)

return test_cases


fn load_test_cases(
toml: tomlmojo.parser.TOMLDocument, table_name: String
Expand Down
Loading