Skip to content

feat: improve fp math conversion API#264

Open
ericnordelo wants to merge 13 commits intorelease-v1.1from
feat/improve-fpmath-conversion-API
Open

feat: improve fp math conversion API#264
ericnordelo wants to merge 13 commits intorelease-v1.1from
feat/improve-fpmath-conversion-API

Conversation

@ericnordelo
Copy link
Copy Markdown
Member

@ericnordelo ericnordelo commented Mar 27, 2026

Resolves #267.

Summary by CodeRabbit

  • New Features

    • Added whole-number conversion functions for UD30x9 and SD29x9 with scaling and truncation variants
    • Added fallible (try_) and non-fallible conversion options with overflow handling
    • Added raw casting support for SD29x9
  • Documentation

    • Clarified distinction between raw casting (bit-preserving) and semantic conversions (scale-applying)
  • Tests

    • Added comprehensive test coverage for UD30x9 and SD29x9 conversions
  • Refactor

    • Consolidated fixed-point constants and utilities into a shared module to reduce duplication

Copilot AI review requested due to automatic review settings March 27, 2026 11:14
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 27, 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.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6376e15e-9013-4495-b617-6bcfc45f55c0

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
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request has no description provided. The template requires at least a basic explanation of changes, PR checklist items, and issue reference, but none of this is present. Add a description explaining the conversion API improvements, list completed checklist items (Tests, Documentation, Changelog), and reference any related issue number.
✅ Passed checks (2 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title 'feat: improve fp math conversion API' directly and accurately summarizes the main objective of the pull request, which adds new conversion modules and APIs for fixed-point math types (UD30x9 and SD29x9).

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/improve-fpmath-conversion-API

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

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 27, 2026

Codecov Report

❌ Patch coverage is 98.26087% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.16%. Comparing base (e8dea76) to head (c0f23e4).

Files with missing lines Patch % Lines
math/fixed_point/sources/sd29x9/conversions.move 97.22% 0 Missing and 1 partial ⚠️
math/fixed_point/sources/ud30x9/conversions.move 94.73% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@               Coverage Diff                @@
##           release-v1.1     #264      +/-   ##
================================================
+ Coverage         89.87%   90.16%   +0.28%     
================================================
  Files                19       21       +2     
  Lines              1787     1860      +73     
  Branches            484      493       +9     
================================================
+ Hits               1606     1677      +71     
  Misses              168      168              
- Partials             13       15       +2     
Flag Coverage Δ
contracts/access 44.87% <ø> (ø)
math/core 86.12% <ø> (ø)
math/fixed_point 63.08% <98.26%> (+4.60%) ⬆️

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
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to clarify and improve the fixed-point “conversion vs raw casting” API by expanding the casting_u128 surface and refactoring shared fixed-point constants to a common place.

Changes:

  • Add casting_u128::into_SD29x9(u128, bool) and a test asserting it matches sd29x9::wrap.
  • Refactor SD29x9/UD30x9 implementations to use fixed_point_common::* for scale and bit-constant values.
  • Update README to distinguish “raw casting” from “whole-number conversions”, and update Move.lock with mainnet pins.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
math/fixed_point/tests/sd29x9_tests/wrap_tests.move Adds a new test covering raw u128 -> SD29x9 casting behavior.
math/fixed_point/sources/casting/u128.move Documents and adds raw casting helper into_SD29x9.
math/fixed_point/sources/sd29x9/sd29x9.move Switches constants/limits to fixed_point_common.
math/fixed_point/sources/sd29x9/sd29x9_base.move Switches scale/bit constants to fixed_point_common (including in pow).
math/fixed_point/sources/ud30x9/ud30x9.move Switches scale/max constants to fixed_point_common.
math/fixed_point/sources/ud30x9/ud30x9_base.move Switches scale/bit constants to fixed_point_common (including in pow).
math/fixed_point/README.md Updates docs/examples around raw casting vs conversion modules.
math/fixed_point/Move.lock Adds pinned mainnet entries.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

@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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
math/fixed_point/tests/sd29x9_tests/conversion_tests.move (1)

33-57: Optional: factor repeated max_whole setup into a helper.

This would trim duplication and make boundary intent easier to maintain across tests.

♻️ Suggested cleanup
+fun max_whole(): u128 {
+    MAX_POSITIVE_VALUE / SCALE
+}
+
 #[test]
 fun from_u128_scales_max_supported_whole_magnitude() {
-    let max_whole = MAX_POSITIVE_VALUE / SCALE;
+    let max_whole = max_whole();
     let positive = sd29x9_convert::from_u128(max_whole, false);
     let negative = sd29x9_convert::from_u128(max_whole, true);
@@
 #[test]
 fun try_from_u128_returns_some_for_max_supported_whole_magnitude() {
-    let max_whole = MAX_POSITIVE_VALUE / SCALE;
+    let max_whole = max_whole();
     let expected = sd29x9::wrap(max_whole * SCALE, false);
     assert_eq!(sd29x9_convert::try_from_u128(max_whole, false), option::some(expected));
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@math/fixed_point/tests/sd29x9_tests/conversion_tests.move` around lines 33 -
57, Several tests in this file repeat computing max_whole = MAX_POSITIVE_VALUE /
SCALE; factor that into a small helper (e.g., a private module-level function or
a test helper like fn max_supported_whole() -> u128) and replace the repeated
lines in tests from_u128_aborts_when_scaled_value_overflows,
try_from_u128_returns_none_when_scaled_value_overflows,
try_from_u128_returns_some_for_max_supported_whole_magnitude, and the earlier
conversion test to call that helper; ensure the helper returns the same type
used by sd29x9_convert::from_u128 and sd29x9::try_from_u128 and keep existing
assertions unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@math/fixed_point/sources/conversions/sd29x9.move`:
- Around line 118-121: to_u128_trunc (and try_to_u128_trunc) currently trust the
is_negative returned by to_parts_trunc which intentionally clears the sign for
values with whole == 0 (e.g., -0.5), allowing negative fractionals to slip
through; update to_u128_trunc and try_to_u128_trunc to inspect the original
SD29x9 sign directly (e.g., via an existing raw/sign accessor or an
is_negative_raw helper) before truncation and abort/return none for any negative
input, rather than relying on to_parts_trunc's is_negative; ensure to_u64_trunc
(which calls to_u128_trunc) inherits this corrected behavior.

---

Nitpick comments:
In `@math/fixed_point/tests/sd29x9_tests/conversion_tests.move`:
- Around line 33-57: Several tests in this file repeat computing max_whole =
MAX_POSITIVE_VALUE / SCALE; factor that into a small helper (e.g., a private
module-level function or a test helper like fn max_supported_whole() -> u128)
and replace the repeated lines in tests
from_u128_aborts_when_scaled_value_overflows,
try_from_u128_returns_none_when_scaled_value_overflows,
try_from_u128_returns_some_for_max_supported_whole_magnitude, and the earlier
conversion test to call that helper; ensure the helper returns the same type
used by sd29x9_convert::from_u128 and sd29x9::try_from_u128 and keep existing
assertions unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cc2283b7-14ee-4420-a4b6-f1ba7cb064cc

📥 Commits

Reviewing files that changed from the base of the PR and between fe68f90 and 7377ee9.

⛔ Files ignored due to path filters (1)
  • math/fixed_point/Move.lock is excluded by !**/*.lock
📒 Files selected for processing (12)
  • math/fixed_point/README.md
  • math/fixed_point/sources/casting/u128.move
  • math/fixed_point/sources/conversions/sd29x9.move
  • math/fixed_point/sources/conversions/ud30x9.move
  • math/fixed_point/sources/internal/common.move
  • math/fixed_point/sources/sd29x9/sd29x9.move
  • math/fixed_point/sources/sd29x9/sd29x9_base.move
  • math/fixed_point/sources/ud30x9/ud30x9.move
  • math/fixed_point/sources/ud30x9/ud30x9_base.move
  • math/fixed_point/tests/sd29x9_tests/conversion_tests.move
  • math/fixed_point/tests/sd29x9_tests/wrap_tests.move
  • math/fixed_point/tests/ud30x9_tests/conversion_tests.move

Copy link
Copy Markdown
Collaborator

@bidzyyys bidzyyys left a comment

Choose a reason for hiding this comment

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

Looks good to me!

@ericnordelo ericnordelo requested review from 0xNeshi and bidzyyys March 30, 2026 10:47
Copilot AI review requested due to automatic review settings March 30, 2026 10:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 13 out of 14 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings March 30, 2026 12:42
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Collaborator

@0xNeshi 0xNeshi left a comment

Choose a reason for hiding this comment

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

Left responses to previous comments (see above)

@bidzyyys bidzyyys changed the title Improve fp math conversion API feat: improve fp math conversion API Mar 31, 2026
Copilot AI review requested due to automatic review settings April 1, 2026 11:20
@ericnordelo ericnordelo requested a review from 0xNeshi April 1, 2026 11:21
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 15 changed files in this pull request and generated 3 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Collaborator

@0xNeshi 0xNeshi left a comment

Choose a reason for hiding this comment

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

nits

/// #### Returns
/// - `floor(u128::MAX / 10^9)`.
public(package) fun max_ud30x9_whole(): u128 {
(std::u128::max_value!()) / SCALE
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
(std::u128::max_value!()) / SCALE
std::u128::max_value!() / SCALE

nit

let inverted = bits ^ std::u128::max_value!();
let sum = (inverted as u256) + 1;
(sum & (U128_MAX_VALUE as u256)) as u128
(sum & ((std::u128::max_value!()) as u256)) as u128
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
(sum & ((std::u128::max_value!()) as u256)) as u128
(sum & (std::u128::max_value!() as u256)) as u128

nit: there are a couple of other places in the PR where redundant brackets are used like (std::u128::max_value!())

} else {
let shifted = raw >> bits;
let mask = U128_MAX_VALUE << (128 - bits);
let mask = (std::u128::max_value!()) << (128 - bits);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Suggested change
let mask = (std::u128::max_value!()) << (128 - bits);
let mask = std::u128::max_value!() << (128 - bits);

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.

[M-01]: Missing Scaled Conversion Functions Between Integer and Fixed-Point Types

4 participants