/// math.sol -- mixin for inline numerical wizardry // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see . // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; library DSMath { uint256 public constant WAD = 10 ** 18; uint256 public constant RAY = 10 ** 27; //rounds to zero if x*y < WAD / 2 function wmul(uint256 x, uint256 y) internal pure returns (uint256) { return ((x * y) + (WAD / 2)) / WAD; } //rounds to zero if x*y < WAD / 2 function wdiv(uint256 x, uint256 y) internal pure returns (uint256) { return ((x * WAD) + (y / 2)) / y; } function reciprocal(uint256 x) internal pure returns (uint256) { return wdiv(WAD, x); } // This famous algorithm is called "exponentiation by squaring" // and calculates x^n with x as fixed-point and n as regular unsigned. // // It's O(log n), instead of O(n) for naive repeated multiplication. // // These facts are why it works: // // If n is even, then x^n = (x^2)^(n/2). // If n is odd, then x^n = x * x^(n-1), // and applying the equation for even x gives // x^n = x * (x^2)^((n-1) / 2). // // Also, EVM division is flooring and // floor[(n-1) / 2] = floor[n / 2]. // function rpow(uint256 x, uint256 n) internal pure returns (uint256 z) { z = n % 2 != 0 ? x : RAY; for (n /= 2; n != 0; n /= 2) { x = rmul(x, x); if (n % 2 != 0) { z = rmul(z, x); } } } //rounds to zero if x*y < WAD / 2 function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) { z = ((x * y) + (RAY / 2)) / RAY; } }