Skip to content

fix: inconsistent shift behavior in fixed-point math library#201

Merged
bidzyyys merged 2 commits intomainfrom
165-bug-inconsistent-shift-behavior-in-fixed-point-math-library
Mar 3, 2026
Merged

fix: inconsistent shift behavior in fixed-point math library#201
bidzyyys merged 2 commits intomainfrom
165-bug-inconsistent-shift-behavior-in-fixed-point-math-library

Conversation

@bidzyyys
Copy link
Collaborator

@bidzyyys bidzyyys commented Mar 3, 2026

Resolves #165

Summary by CodeRabbit

  • Bug Fixes

    • Fixed lshift and rshift operations to handle large bit shifts (≥128 bits) by returning zero instead of aborting, enabling more graceful handling of edge cases.
  • Tests

    • Updated test suite to verify new shift behavior, including tests for shifts up to 255 bits, confirming all large shifts return zero.

@bidzyyys bidzyyys linked an issue Mar 3, 2026 that may be closed by this pull request
@bidzyyys bidzyyys self-assigned this Mar 3, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 3, 2026

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The UD30x9 fixed-point math implementation now includes bounds checks in lshift and rshift functions to return zero for shifts of 128 bits or more, replacing previous abort behavior. Corresponding test updates verify the new zero-return behavior for edge cases.

Changes

Cohort / File(s) Summary
UD30x9 shift function improvements
math/fixed_point/sources/ud30x9/ud30x9_base.move
Added bounds checks to lshift and rshift functions to gracefully return zero for shifts >= 128 bits instead of allowing undefined behavior.
UD30x9 test updates
math/fixed_point/tests/ud30x9_tests.move
Updated tests to assert zero return values for lshift(128) and rshift(128) instead of expecting aborts; added new tests for shifts at 255 bits confirming zero results.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • immrsd
  • 0xNeshi

Poem

🐰 A hop through bounds so grand,
Where shifts no longer take a stand,
At 128 they gracefully cease,
Returning zero for our peace,
Consistency hops across the land! 🎯

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The PR description only references the issue number without providing details about changes, context, or addressing template sections like tests/documentation. Expand the description to explain what was changed and why (the addition of bounds checks), and indicate status of tests, documentation, and changelog.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main change: fixing inconsistent shift behavior in the fixed-point math library by adding bounds checks to lshift and rshift functions.
Linked Issues check ✅ Passed The code changes successfully address issue #165 by making UD30x9 shift behavior consistent with SD29x9 through bounds checks that gracefully return zero for large shifts instead of aborting.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the inconsistent shift behavior issue: bounds checks in lshift/rshift functions and updated tests to verify graceful handling of large shifts.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 165-bug-inconsistent-shift-behavior-in-fixed-point-math-library

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Mar 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.60%. Comparing base (06b768b) to head (d1c83cb).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #201      +/-   ##
==========================================
+ Coverage   95.58%   95.60%   +0.01%     
==========================================
  Files          19       19              
  Lines        1541     1548       +7     
  Branches      389      394       +5     
==========================================
+ Hits         1473     1480       +7     
  Misses         48       48              
  Partials       20       20              
Flag Coverage Δ
contracts/access 50.19% <ø> (ø)
math/core 94.21% <ø> (ø)
math/fixed_point 68.68% <100.00%> (+0.54%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
math/fixed_point/sources/ud30x9/ud30x9_base.move (1)

86-87: Document the new bits >= 128 => 0 behavior in function docs.

The implementation changed semantics at the boundary; the doc comments should state this explicitly to avoid API ambiguity.

Proposed doc update
-/// Implements the left shift operation (<<) for `UD30x9` type.
+/// Implements the left shift operation (<<) for `UD30x9` type.
+/// Returns zero when `bits >= 128`.
 public fun lshift(x: UD30x9, bits: u8): UD30x9 {
@@
-/// Implements the right shift operation (>>) for `UD30x9` type.
+/// Implements the right shift operation (>>) for `UD30x9` type.
+/// Returns zero when `bits >= 128`.
 public fun rshift(x: UD30x9, bits: u8): UD30x9 {

Also applies to: 158-159

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@math/fixed_point/sources/ud30x9/ud30x9_base.move` around lines 86 - 87, The
function docs for lshift (and the analogous right-shift function at the same
region) must explicitly state the new boundary behavior: when the shift amount
bits is >= 128 the result is defined to be 0; update the doc comment above
public fun lshift(x: UD30x9, bits: u8): UD30x9 to mention "bits >= 128 => 0" and
add the same clarifying sentence to the doc comment for the corresponding rshift
function (the other shift function at lines ~158-159) so callers are aware of
the changed semantics and the exact behavior at the boundary.
math/fixed_point/tests/ud30x9_tests.move (1)

122-144: Add bits = 127 boundary tests to guard off-by-one regressions.

You now assert saturation at and above 128; adding explicit 127 checks would lock down the threshold behavior.

Suggested test additions
+#[test]
+fun lshift_by_127_keeps_shift_semantics() {
+    let x = fixed(1);
+    expect(x.lshift(127), fixed(1u128 << 127));
+}
+
+#[test]
+fun rshift_by_127_keeps_shift_semantics() {
+    let x = fixed(MAX_VALUE);
+    expect(x.rshift(127), fixed(1));
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@math/fixed_point/tests/ud30x9_tests.move` around lines 122 - 144, Add two
boundary tests for the 127-bit case to prevent off-by-one regressions: in
math/fixed_point/tests/ud30x9_tests.move add a lshift_by_127_not_zero test and a
rshift_by_127_not_zero test that use let x = fixed(1) and call x.lshift(127) and
x.rshift(127) respectively, asserting the results are not equal to fixed(0)
(i.e., expect non-zero) so the threshold at 128 is explicitly verified; place
them alongside the existing lshift_by_128_returns_zero and
rshift_by_128_returns_zero tests.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@math/fixed_point/sources/ud30x9/ud30x9_base.move`:
- Around line 86-87: The function docs for lshift (and the analogous right-shift
function at the same region) must explicitly state the new boundary behavior:
when the shift amount bits is >= 128 the result is defined to be 0; update the
doc comment above public fun lshift(x: UD30x9, bits: u8): UD30x9 to mention
"bits >= 128 => 0" and add the same clarifying sentence to the doc comment for
the corresponding rshift function (the other shift function at lines ~158-159)
so callers are aware of the changed semantics and the exact behavior at the
boundary.

In `@math/fixed_point/tests/ud30x9_tests.move`:
- Around line 122-144: Add two boundary tests for the 127-bit case to prevent
off-by-one regressions: in math/fixed_point/tests/ud30x9_tests.move add a
lshift_by_127_not_zero test and a rshift_by_127_not_zero test that use let x =
fixed(1) and call x.lshift(127) and x.rshift(127) respectively, asserting the
results are not equal to fixed(0) (i.e., expect non-zero) so the threshold at
128 is explicitly verified; place them alongside the existing
lshift_by_128_returns_zero and rshift_by_128_returns_zero tests.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 06b768b and f2c8469.

📒 Files selected for processing (2)
  • math/fixed_point/sources/ud30x9/ud30x9_base.move
  • math/fixed_point/tests/ud30x9_tests.move

Copy link
Collaborator

@immrsd immrsd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Slightly improved the doc to be more informative and consistent with SD29x9 docs

Copy link
Member

@ericnordelo ericnordelo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@bidzyyys bidzyyys merged commit 7f62467 into main Mar 3, 2026
14 checks passed
@bidzyyys bidzyyys deleted the 165-bug-inconsistent-shift-behavior-in-fixed-point-math-library branch March 3, 2026 10:40
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.

[Bug]: Inconsistent shift behavior in fixed-point math library

3 participants