Skip to content

Commit

Permalink
feat: add value types SD1x18 and UD2x18
Browse files Browse the repository at this point in the history
  • Loading branch information
PaulRBerg committed Dec 13, 2022
1 parent bd866b9 commit c971040
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 1 deletion.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Common Changelog](https://common-changelog.org/), and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

[3.1.0]: https://github.com/paulrberg/prb-math/compare/v3.0.0...v3.1.0
[3.0.0]: https://github.com/paulrberg/prb-math/compare/v2.5.0...v3.0.0
[2.5.0]: https://github.com/paulrberg/prb-math/compare/v2.4.3...v2.5.0
[2.4.3]: https://github.com/paulrberg/prb-math/compare/v2.4.2...v2.4.3
Expand All @@ -24,6 +25,12 @@ The format is based on [Common Changelog](https://common-changelog.org/), and th
[1.0.1]: https://github.com/paulrberg/prb-math/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.com/paulrberg/prb-math/releases/tag/v1.0.0

## [3.1.0] - 2022-12-13

### Added

- Value types `SD1x18` and `UD2x18` (@paulrberg)

## [3.0.0] - 2022-11-29

[1b82ea]: https://github.com/paulrberg/prb-math/commit/1b82ea
Expand Down
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,18 @@ function addRshiftEq() pure returns (bool result) {
```

### Adjacent Value Types

PRBMath provides adjacent value types that serve as abstractions over other vanilla types such as `int64`. The types currently available are:

- `SD1x18` (int64)
- `UD2x18` (uint64)

These are useful if you want to save gas by using a lower bit width integer, e.g. in a struct.

Note that these types don't have any mathematical functionality. For that, you will have to unwrap them into a simple integer and then to the core
types `SD59x18` and `UD60x18`.

### Assertions

PRBMath is shipped with typed assertions that you can use for writing tests with [PRBTest](https://github.com/paulrberg/prb-test), which is based on
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@prb/math",
"description": "Solidity library for advanced fixed-point math",
"version": "3.0.0",
"version": "3.1.0",
"author": {
"name": "Paul Razvan Berg",
"url": "https://github.com/paulrberg"
Expand Down
16 changes: 16 additions & 0 deletions src/SD1x18.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.13;

/// @notice The signed 1.18-decimal fixed-point number representation, which can have up to 1 digit and up to 18 decimals.
/// The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity type int64.
/// This is useful when end users want to use int64 to save gas, e.g. with tight variable packing in contract storage.
type SD1x18 is int64;

/*//////////////////////////////////////////////////////////////////////////
CONVERSION FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/

/// @notice Wraps a signed integer into the SD1x18 type.
function sd1x18(int64 x) pure returns (SD1x18 result) {
result = SD1x18.wrap(x);
}
16 changes: 16 additions & 0 deletions src/UD2x18.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.13;

/// @notice The unsigned 2.18-decimal fixed-point number representation, which can have up to 2 digits and up to 18 decimals.
/// The values of this are bound by the minimum and the maximum values permitted by the underlying Solidity type uint64.
/// This is useful when end users want to use uint64 to save gas, e.g. with tight variable packing in contract storage.
type UD2x18 is uint64;

/*//////////////////////////////////////////////////////////////////////////
CONVERSION FUNCTIONS
//////////////////////////////////////////////////////////////////////////*/

/// @notice Wraps a signed integer into the UD2x18 type.
function ud2x18(uint64 x) pure returns (UD2x18 result) {
result = UD2x18.wrap(x);
}
50 changes: 50 additions & 0 deletions src/test/Assertions.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,54 +3,104 @@ pragma solidity >=0.8.13;

import { PRBTest } from "@prb/test/PRBTest.sol";

import { SD1x18 } from "../SD1x18.sol";
import { SD59x18 } from "../SD59x18.sol";
import { UD2x18 } from "../UD2x18.sol";
import { UD60x18 } from "../UD60x18.sol";

contract Assertions is PRBTest {
function assertEq(SD1x18 a, SD1x18 b) internal {
assertEq(SD1x18.unwrap(a), SD1x18.unwrap(b));
}

function assertEq(SD59x18 a, SD59x18 b) internal {
assertEq(SD59x18.unwrap(a), SD59x18.unwrap(b));
}

function assertEq(SD1x18 a, SD1x18 b, string memory err) internal {
assertEq(SD1x18.unwrap(a), SD1x18.unwrap(b), err);
}

function assertEq(SD59x18 a, SD59x18 b, string memory err) internal {
assertEq(SD59x18.unwrap(a), SD59x18.unwrap(b), err);
}

function assertEq(SD1x18 a, int256 b) internal {
assertEq(SD1x18.unwrap(a), b);
}

function assertEq(SD59x18 a, int256 b) internal {
assertEq(SD59x18.unwrap(a), b);
}

function assertEq(SD1x18 a, int256 b, string memory err) internal {
assertEq(SD1x18.unwrap(a), b, err);
}

function assertEq(SD59x18 a, int256 b, string memory err) internal {
assertEq(SD59x18.unwrap(a), b, err);
}

function assertEq(int256 a, SD1x18 b) internal {
assertEq(a, SD1x18.unwrap(b));
}

function assertEq(int256 a, SD59x18 b) internal {
assertEq(a, SD59x18.unwrap(b));
}

function assertEq(int256 a, SD1x18 b, string memory err) internal {
assertEq(a, SD1x18.unwrap(b), err);
}

function assertEq(int256 a, SD59x18 b, string memory err) internal {
assertEq(a, SD59x18.unwrap(b), err);
}

function assertEq(UD2x18 a, UD2x18 b) internal {
assertEq(UD2x18.unwrap(a), UD2x18.unwrap(b));
}

function assertEq(UD60x18 a, UD60x18 b) internal {
assertEq(UD60x18.unwrap(a), UD60x18.unwrap(b));
}

function assertEq(UD2x18 a, UD2x18 b, string memory err) internal {
assertEq(UD2x18.unwrap(a), UD2x18.unwrap(b), err);
}

function assertEq(UD60x18 a, UD60x18 b, string memory err) internal {
assertEq(UD60x18.unwrap(a), UD60x18.unwrap(b), err);
}

function assertEq(UD2x18 a, uint256 b) internal {
assertEq(UD2x18.unwrap(a), b);
}

function assertEq(UD60x18 a, uint256 b) internal {
assertEq(UD60x18.unwrap(a), b);
}

function assertEq(UD2x18 a, uint256 b, string memory err) internal {
assertEq(UD2x18.unwrap(a), b, err);
}

function assertEq(UD60x18 a, uint256 b, string memory err) internal {
assertEq(UD60x18.unwrap(a), b, err);
}

function assertEq(uint256 a, UD2x18 b) internal {
assertEq(a, UD2x18.unwrap(b));
}

function assertEq(uint256 a, UD60x18 b) internal {
assertEq(a, UD60x18.unwrap(b));
}

function assertEq(uint256 a, UD2x18 b, string memory err) internal {
assertEq(a, UD2x18.unwrap(b), err);
}

function assertEq(uint256 a, UD60x18 b, string memory err) internal {
assertEq(a, UD60x18.unwrap(b), err);
}
Expand Down
14 changes: 14 additions & 0 deletions test/sd1x18/conversion/SD1x18Conversion.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.13;

import "src/SD1x18.sol";
import { BaseTest } from "../../BaseTest.t.sol";

/// @dev Collection of tests for the conversion functions available in the SD1x18 type.
contract SD1x18__ConversionTest is BaseTest {
function testSd1x18(int64 x) external {
SD1x18 actual = sd1x18(x);
SD1x18 expected = SD1x18.wrap(x);
assertEq(actual, expected);
}
}
14 changes: 14 additions & 0 deletions test/ud2x18/conversion/UD2x18Conversion.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.13;

import "src/UD2x18.sol";
import { BaseTest } from "../../BaseTest.t.sol";

/// @dev Collection of tests for the conversion functions available in the UD2x18 type.
contract UD2x18__ConversionTest is BaseTest {
function testUd2x18(uint64 x) external {
UD2x18 actual = ud2x18(x);
UD2x18 expected = UD2x18.wrap(x);
assertEq(actual, expected);
}
}

0 comments on commit c971040

Please sign in to comment.