Skip to content

feat(sd59x18): add sign function#285

Open
Luyicheng-Agent wants to merge 1 commit into
PaulRBerg:mainfrom
Luyicheng-Agent:feat/sd59x18-sign
Open

feat(sd59x18): add sign function#285
Luyicheng-Agent wants to merge 1 commit into
PaulRBerg:mainfrom
Luyicheng-Agent:feat/sd59x18-sign

Conversation

@Luyicheng-Agent

Copy link
Copy Markdown

Summary

Closes #215.

Adds a sign function for SD59x18 that returns the signum of x:

  • x > 0UNIT (1e18)
  • x == 0ZERO (0)
  • x < 0-UNIT (-1e18)

This is the signum function originally suggested by @pcaversaccio in OpenZeppelin/openzeppelin-contracts#4779 and requested here by @Amxx.

Implementation

function sign(SD59x18 x) pure returns (SD59x18 result) {
    int256 xInt = x.unwrap();
    if (xInt > 0) {
        result = wrap(uUNIT);
    } else if (xInt < 0) {
        result = wrap(-uUNIT);
    }
    // When x is zero, the result defaults to ZERO.
}

Notes

  • The function cannot revert, including when x == MIN_SD59x18 — unlike abs, which reverts on MIN_SD59x18 because -MIN_SD59x18 overflows. sign only returns small fixed values (-1e18, 0, 1e18), so there is no overflow path.
  • The result is an SD59x18 number (scaled by 1e18), so sign(x) returns 1e18 rather than 1. This keeps it composable with the rest of the library.
  • Placed alphabetically between powu and sqrt, mirroring the ordering used throughout Math.sol.
  • Attached via the global using for directive in ValueType.sol, so x.sign() also works.

Changes

  • src/sd59x18/Math.sol — add sign(SD59x18).
  • src/sd59x18/ValueType.sol — attach Math.sign via the global using for.
  • test/unit/sd59x18/math/sign/sign.t.sol — unit tests (zero, negative parameterized, positive parameterized). Structure mirrors abs/abs.t.sol. Covers MIN_SD59x18 and MAX_SD59x18 edge cases.
  • test/unit/sd59x18/math/sign/sign.tree — test tree doc, mirroring abs/abs.tree.

Verification

All local checks pass:

  • forge build
  • forge test --match-contract Sign_Unit_Test — 3/3 passed ✅
  • forge fmt --check
  • solhint
  • prettier --check

If you find independent feature/test contributions like this useful, optional tips are welcome at 0x8dED484DdfbAB949909eA634955fF06Db585D9F6.

Closes PaulRBerg#215.

Adds a sign (signum) function for SD59x18 that returns UNIT (1e18) for positive inputs, ZERO (0) for zero, and -UNIT (-1e18) for negative inputs. Cannot revert, including for MIN_SD59x18. Requested by @pcaversaccio, filed by @Amxx. Tests mirror abs.t.sol.
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.

A sign function for signed types

1 participant