Skip to content

[ABA-26] fix(vortex-array): scale-compensate Decimal scalar mul/div#9

Open
abnobdoss wants to merge 2 commits into
developfrom
fix/aba-26-decimal-scalar-mul-div-scale
Open

[ABA-26] fix(vortex-array): scale-compensate Decimal scalar mul/div#9
abnobdoss wants to merge 2 commits into
developfrom
fix/aba-26-decimal-scalar-mul-div-scale

Conversation

@abnobdoss
Copy link
Copy Markdown
Owner

Summary

  • DecimalScalar::checked_binary_numeric previously computed lhs_raw * rhs_raw for Mul and lhs_raw / rhs_raw for Div, ignoring the decimal scale entirely.
  • At scale S, the correct raw-integer semantics are:
    • Mul: result_raw = (lhs_raw * rhs_raw) / 10^S
    • Div: result_raw = (lhs_raw * 10^S) / rhs_raw
  • Fix: compute scale_factor = i256::from_i128(10).checked_pow(scale as u32) and apply it in the Mul/Div arms. Negative scale returns None (unused for mul/div today). Intermediate overflow also returns None, consistent with existing checked-arithmetic semantics.
  • Two pre-existing tests that asserted the buggy behaviour are corrected:
    • test_decimal_scalar_checked_mul: expected raw 500 → corrected to 5
    • test_decimal_scalar_checked_div: expected raw 100 → corrected to 10000

Linear

Closes ABA-26

Validation

cargo test -p vortex-array decimal  # 217 passed, 0 failed

Test issue_aba26_decimal_scalar_mul_div_compensate_scale (added in commit 1) confirms the bug was present before the fix and passes after.


🤖 Generated with Claude Code

Abanoub Doss and others added 2 commits May 21, 2026 08:13
…scale

Add failing test `issue_aba26_decimal_scalar_mul_div_compensate_scale`
that demonstrates decimal mul/div in `checked_binary_numeric` do not
apply scale compensation:
  - 1.0 * 1.0 at scale=1 returns raw 100 (10.0) instead of 10 (1.0)
  - 2.5 * 4.0 at scale=1 returns raw 1000 (100.0) instead of 100 (10.0)
  - 10.0 / 2.0 at scale=1 returns raw 5 (0.5) instead of 50 (5.0)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Abanoub Doss <abanoub.doss@gmail.com>
`checked_binary_numeric` previously computed raw * raw for Mul and
raw / raw for Div, ignoring the decimal scale.  At scale S:

  mul: result_raw = (lhs_raw * rhs_raw) / 10^S
  div: result_raw = (lhs_raw * 10^S) / rhs_raw

Both paths now compute the scale_factor via `i256::checked_pow(scale
as u32)` before the operation.  Negative scale returns None (not yet
used for mul/div); intermediate overflow also returns None, consistent
with existing checked_* semantics.

Two pre-existing tests that asserted the buggy behaviour are updated:
  - test_decimal_scalar_checked_mul: expected 500 → corrected to 5
  - test_decimal_scalar_checked_div: expected 100 → corrected to 10000

Fixes ABA-26.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Abanoub Doss <abanoub.doss@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant