Description
The helper function _parse_numeric_exact incorrectly parses scientific notation inputs like 1e6 and 1e8 as hexadecimal values instead of decimal/scientific notation.
This leads to silent incorrect results in both math_operation and compare_numbers.
Steps to Reproduce
from backend.calc_functions.calc_func import _parse_numeric_exact, math_operation, compare_numbers
_parse_numeric_exact("1e6") # returns 486 (expected: 1000000)
_parse_numeric_exact("1e8") # returns 488 (expected: 100000000)
math_operation(["1e8", "+", "1"]) # returns "489" (expected: "100000001")
compare_numbers(["1e8", ">", "1000000"]) # returns "false" (expected: "true")
Expected Behavior
Actual Behavior
-
"1e6" → 486 (interpreted as hex 0x1e6)
-
"1e8" → 488 (interpreted as hex 0x1e8)
-
Downstream calculations produce incorrect results without any error
Root Cause
In _parse_numeric_exact, the hex-detection logic runs before attempting to parse with Decimal.
if all(c in "0123456789abcdefABCDEF" for c in s) and any(c in "abcdefABCDEF" for c in s):
return int(s, 16)
Strings like "1e6" satisfy this condition (e is treated as a hex character), so they are incorrectly parsed as hexadecimal.
Suggested Fix
Attempt decimal parsing before applying the ambiguous hex-detection logic:
if s.lower().startswith("0x"):
return int(s, 16)
if re.fullmatch(r"[+-]?\d+", s):
return int(s, 10)
try:
return Decimal(s)
except InvalidOperation:
pass
if all(c in "0123456789abcdefABCDEF" for c in s) and any(c in "abcdefABCDEF" for c in s):
return int(s, 16)
Impact
-
Produces incorrect results silently
-
Affects core calculation features
-
Particularly problematic for values like "1e8" (commonly used for satoshis / BTC)
Additional Context
This format (1e6, 1e8) is already mentioned as supported in the function’s docstring, so current behavior contradicts documentation.
Description
The helper function _parse_numeric_exact incorrectly parses scientific notation inputs like 1e6 and 1e8 as hexadecimal values instead of decimal/scientific notation.
This leads to silent incorrect results in both math_operation and compare_numbers.
Steps to Reproduce
Expected Behavior
"1e6" → 1000000
"1e8" → 100000000
Calculations and comparisons should use correct decimal values
Actual Behavior
"1e6" → 486 (interpreted as hex 0x1e6)
"1e8" → 488 (interpreted as hex 0x1e8)
Downstream calculations produce incorrect results without any error
Root Cause
In _parse_numeric_exact, the hex-detection logic runs before attempting to parse with Decimal.
Strings like "1e6" satisfy this condition (e is treated as a hex character), so they are incorrectly parsed as hexadecimal.
Suggested Fix
Attempt decimal parsing before applying the ambiguous hex-detection logic:
Impact
Produces incorrect results silently
Affects core calculation features
Particularly problematic for values like "1e8" (commonly used for satoshis / BTC)
Additional Context
This format (1e6, 1e8) is already mentioned as supported in the function’s docstring, so current behavior contradicts documentation.