Rename rounding modes and complete with fourth (#4455)
Co-authored-by: ernestognw <ernestognw@gmail.com>
This commit is contained in:
@ -13,9 +13,10 @@ library Math {
|
||||
error MathOverflowedMulDiv();
|
||||
|
||||
enum Rounding {
|
||||
Down, // Toward negative infinity
|
||||
Up, // Toward infinity
|
||||
Zero // Toward zero
|
||||
Floor, // Toward negative infinity
|
||||
Ceil, // Toward positive infinity
|
||||
Trunc, // Toward zero
|
||||
Expand // Away from zero
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,8 +101,8 @@ library Math {
|
||||
/**
|
||||
* @dev Returns the ceiling of the division of two numbers.
|
||||
*
|
||||
* This differs from standard division with `/` in that it rounds up instead
|
||||
* of rounding down.
|
||||
* This differs from standard division with `/` in that it rounds towards infinity instead
|
||||
* of rounding towards zero.
|
||||
*/
|
||||
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
|
||||
if (b == 0) {
|
||||
@ -206,14 +207,15 @@ library Math {
|
||||
*/
|
||||
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
|
||||
uint256 result = mulDiv(x, y, denominator);
|
||||
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
|
||||
if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
|
||||
result += 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
|
||||
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
|
||||
* towards zero.
|
||||
*
|
||||
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
|
||||
*/
|
||||
@ -256,12 +258,12 @@ library Math {
|
||||
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
|
||||
unchecked {
|
||||
uint256 result = sqrt(a);
|
||||
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
|
||||
return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return the log in base 2, rounded down, of a positive value.
|
||||
* @dev Return the log in base 2 of a positive value rounded towards zero.
|
||||
* Returns 0 if given 0.
|
||||
*/
|
||||
function log2(uint256 value) internal pure returns (uint256) {
|
||||
@ -309,12 +311,12 @@ library Math {
|
||||
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
|
||||
unchecked {
|
||||
uint256 result = log2(value);
|
||||
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
|
||||
return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return the log in base 10, rounded down, of a positive value.
|
||||
* @dev Return the log in base 10 of a positive value rounded towards zero.
|
||||
* Returns 0 if given 0.
|
||||
*/
|
||||
function log10(uint256 value) internal pure returns (uint256) {
|
||||
@ -358,12 +360,12 @@ library Math {
|
||||
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
|
||||
unchecked {
|
||||
uint256 result = log10(value);
|
||||
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
|
||||
return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Return the log in base 256, rounded down, of a positive value.
|
||||
* @dev Return the log in base 256 of a positive value rounded towards zero.
|
||||
* Returns 0 if given 0.
|
||||
*
|
||||
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
|
||||
@ -401,7 +403,14 @@ library Math {
|
||||
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
|
||||
unchecked {
|
||||
uint256 result = log256(value);
|
||||
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
|
||||
return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
|
||||
*/
|
||||
function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
|
||||
return uint8(rounding) % 2 == 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user