Last active
June 21, 2023 18:03
-
-
Save 0xCourtney/c91581ea0e94f912a745628739c9193c to your computer and use it in GitHub Desktop.
Rounding with PRBMath
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.0; | |
import {UD60x18} from "@prb/math/UD60x18.sol"; | |
import {SD59x18} from "@prb/math/SD59x18.sol"; | |
library PRBMathRounding { | |
SD59x18 constant iONE = SD59x18.wrap(1e18); | |
SD59x18 constant iTEN = SD59x18.wrap(10e18); | |
UD60x18 constant ONE_THOUSAND = UD60x18.wrap(1000e18); | |
/// @notice Rounds `n` to the `d` digit from the highest digit | |
/// https://www.desmos.com/calculator/bhbzwyrkjm | |
/// @param n The number to round (18 decimals) | |
/// @param d The number of digits from the highest digit (18 decimals) | |
function roundTo(UD60x18 n, UD60x18 d) internal pure returns (UD60x18) { | |
SD59x18 v = n.intoSD59x18().log10().sub(d).floor(); | |
SD59x18 r = n.intoSD59x18().div(iTEN.pow(v)); | |
r = r.frac() < iONE_HALF ? r.floor() : r.ceil(); | |
UD60x18 s = r.mul(iTEN.pow(v)).intoUD60x18(); | |
return n < ONE_THOUSAND ? s : s.ceil(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment