Skip to content

Commit

Permalink
Merge pull request #192 from EthTx/dudzicz/update_decimal_format
Browse files Browse the repository at this point in the history
Update and improve decimal format
  • Loading branch information
dudzicz authored May 16, 2023
2 parents 145f134 + 9defb05 commit 21e46e3
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repos:
alias: ethtx-black

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: check-ast
Expand Down
23 changes: 6 additions & 17 deletions ethtx/decoders/semantic/helpers/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@

import logging
from functools import partial
from decimal import Decimal
from decimal import Decimal, getcontext

from ethtx.decoders.decoders.parameters import decode_function_parameters
from ethtx.models.decoded_model import AddressInfo
from ethtx.models.semantics_model import FunctionSemantics
from ethtx.semantics.utilities.functions import add_utils_to_context

DECIMAL_CLASS_MINIMAL_LIMIT = 10**-6
DECIMAL_PRECISION = 256

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -207,19 +207,8 @@ def _handle_decimal_representations(val: Decimal) -> str:
"""Handles argument format for Decimal objects. Converts into a string representation taking into accound border
cases of big integer and small floats.
"""
val_str = str(val)
getcontext().prec = DECIMAL_PRECISION
if val == val.to_integral():
return str(val.to_integral())

# handle the case of small decimal numbers and scientific representation
if val < DECIMAL_CLASS_MINIMAL_LIMIT:
if len(val_str.split("E")) < 2:
return val_str

digits, exponent = val_str.split("E")

digit_part = digits.replace(".", "")
num_zeros = abs(int(exponent)) - 1

new_str_format = ["0.0", "0" * num_zeros, digit_part]
return "".join(new_str_format)

return val_str
return format(val, "f").rstrip("0").rstrip(".")
74 changes: 74 additions & 0 deletions tests/test_decimal_format.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from decimal import Decimal

from ethtx.decoders.semantic.helpers.utils import (
_handle_decimal_representations as handle_decimal_representations,
)


class TestHandleDecimalRepresentations:
def test_handle_decimal_representations(self):
# Test for small int
assert handle_decimal_representations(Decimal(10)) == "10"

# Test for large int
assert (
handle_decimal_representations(Decimal("100000000000000000000000000"))
== "100000000000000000000000000"
)

# Test for small float
assert handle_decimal_representations(Decimal("0.5")) == "0.5"

# Test for large float
assert (
handle_decimal_representations(Decimal("100000000000000000000.5"))
== "100000000000000000000.5"
)

# Test for float with a lot of decimals
assert (
handle_decimal_representations(Decimal("0.12345678901234567890123456789"))
== "0.12345678901234567890123456789"
)

# Test for float with trailing 0s
assert handle_decimal_representations(Decimal("10.500")) == "10.5"

# Test for float with trailing 0s
assert handle_decimal_representations(Decimal("10.000")) == "10"

# Test for float with trailing 0s and leading 0s
assert handle_decimal_representations(Decimal("0.0500")) == "0.05"

# Test cases from the original question
assert (
handle_decimal_representations(Decimal("0.0461872460000")) == "0.046187246"
)
assert handle_decimal_representations(Decimal("0.00000")) == "0"
assert handle_decimal_representations(Decimal("650000000")) == "650000000"
assert (
handle_decimal_representations(Decimal("650000000.0004214000"))
== "650000000.0004214"
)
assert handle_decimal_representations(Decimal("650000.00000000")) == "650000"

# Additional test cases
assert (
handle_decimal_representations(Decimal("0.0000000000000000000000001"))
== "0.0000000000000000000000001"
)
assert (
handle_decimal_representations(
Decimal("0.000000000000000000000000187126874612874612784")
)
== "0.000000000000000000000000187126874612874612784"
)
assert (
handle_decimal_representations(
Decimal("0.000000000000000000000000187126874612874612784000000000")
)
== "0.000000000000000000000000187126874612874612784"
)

# Test that the function returns a string
assert isinstance(handle_decimal_representations(Decimal("1.234")), str)

0 comments on commit 21e46e3

Please sign in to comment.