Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughAdded square root functionality to the fixed-point math library by introducing a shared Changes
Sequence Diagram(s)sequenceDiagram
participant UD30x9 as UD30x9::sqrt()
participant SD29x9 as SD29x9::sqrt()
participant Helper as fp_helpers::sqrt_floor()
participant Newton as Newton Iteration
rect rgba(100, 150, 255, 0.5)
UD30x9->>Helper: sqrt_floor(raw * SCALE)
end
rect rgba(100, 200, 100, 0.5)
SD29x9->>Helper: sqrt_floor(magnitude * SCALE)
end
rect rgba(200, 100, 100, 0.5)
Helper->>Newton: Initial approximation + iterations
Newton->>Newton: (xn + a/xn) >> 1
Newton->>Helper: Refined result
end
Helper-->>UD30x9: floor(sqrt(a))
Helper-->>SD29x9: floor(sqrt(a))
UD30x9->>UD30x9: wrap(result)
SD29x9->>SD29x9: wrap(result as SD29x9)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #286 +/- ##
==========================================
+ Coverage 89.88% 90.01% +0.12%
==========================================
Files 19 20 +1
Lines 1790 1833 +43
Branches 484 503 +19
==========================================
+ Hits 1609 1650 +41
Misses 168 168
- Partials 13 15 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| public fun sqrt(x: UD30x9): UD30x9 { | ||
| let raw = x.unwrap() as u256; | ||
| if (raw == 0) { | ||
| return wrap(0) |
| if (mag == 0) { | ||
| return zero() | ||
| }; | ||
| let result = fp_helpers::sqrt_floor(mag * SCALE); |
There was a problem hiding this comment.
Add comment explaining why * SCALE is necessary
| if (raw == 0) { | ||
| return wrap(0) | ||
| }; | ||
| let result = fp_helpers::sqrt_floor(raw * SCALE_U256); |
There was a problem hiding this comment.
Add comment explaining why * SCALE_U256 is necessary
| public fun sqrt(x: SD29x9): SD29x9 { | ||
| let Components { neg, mag } = decompose(x.unwrap()); | ||
| assert!(!neg, ENegativeSqrt); | ||
| if (mag == 0) { |
There was a problem hiding this comment.
Zero-check is redundant, as sqrt_floor performs it in the first line
|
|
||
| #[test] | ||
| fun sqrt_of_zero_is_zero() { | ||
| expect(fixed(0).sqrt(), fixed(0)); |
There was a problem hiding this comment.
| expect(fixed(0).sqrt(), fixed(0)); | |
| expect(ud30x9::zero().sqrt(), ud30x9::zero()); |
| values.destroy!(|x| { | ||
| let result = x.sqrt(); | ||
| // Result is non-negative: raw bits should not have sign bit set | ||
| assert!(result.unwrap() <= 0x7FFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF_FFFF); |
There was a problem hiding this comment.
It would be useful to have something like sd29x9::is_positive & sd29x9::is_negative, so this assertion would become:
assert!(!result.is_negative());| #[test] | ||
| fun sqrt_result_is_always_non_negative() { |
There was a problem hiding this comment.
| #[test] | |
| fun sqrt_result_is_always_non_negative() { | |
| #[random_test] | |
| fun sqrt_result_is_always_non_negative(raw: u128) { |
Perfect candidate for a prop test
| assert!(r * r <= scaled); | ||
| assert!((r + 1) * (r + 1) > scaled); |
There was a problem hiding this comment.
These assertions are invariants on all non-negative values, making this a good candidate for a proptest.
Alternatively, these invariant assertions could be incorporated into sqrt_result_is_always_non_negative.
| #[test] | ||
| fun sqrt_floor_property_for_non_perfect_squares() { |
There was a problem hiding this comment.
- these invariants hold for all valid values, not just non-perfect squares
- therefore, candidate for prop. test
| #[test] | ||
| fun sqrt_monotonicity() { |
There was a problem hiding this comment.
| #[test] | |
| fun sqrt_monotonicity() { | |
| #[random_test] | |
| fun sqrt_monotonicity(x: u128, y: u128) { |
good candidate for a prop. test
Resolves #90
Summary by CodeRabbit
Release Notes
New Features
Tests