avoid extra check from compiler during math ops
Signed-off-by: Uncle Fatso <uncle.fatso@ghostchain.io>
This commit is contained in:
parent
5e09c9d417
commit
9a6bc55e62
@ -3,10 +3,12 @@ pragma solidity ^0.8.20;
|
|||||||
|
|
||||||
library FullMath {
|
library FullMath {
|
||||||
function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {
|
function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {
|
||||||
uint256 mm = mulmod(x, y, type(uint256).max);
|
unchecked {
|
||||||
l = x * y;
|
uint256 mm = mulmod(x, y, type(uint256).max);
|
||||||
h = mm - l;
|
l = x * y;
|
||||||
if (mm < l) h -= 1;
|
h = mm - l;
|
||||||
|
if (mm < l) h -= 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fullDiv(
|
function fullDiv(
|
||||||
@ -14,20 +16,22 @@ library FullMath {
|
|||||||
uint256 h,
|
uint256 h,
|
||||||
uint256 d
|
uint256 d
|
||||||
) private pure returns (uint256) {
|
) private pure returns (uint256) {
|
||||||
uint256 pow2 = d & (~d + 1);
|
unchecked {
|
||||||
d /= pow2;
|
uint256 pow2 = d & (~d + 1);
|
||||||
l /= pow2;
|
d /= pow2;
|
||||||
l += h * ((~pow2 + 1) / pow2 + 1);
|
l /= pow2;
|
||||||
uint256 r = 1;
|
l += h * ((~pow2 + 1) / pow2 + 1);
|
||||||
r *= 2 - d * r;
|
uint256 r = 1;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
r *= 2 - d * r;
|
r *= 2 - d * r;
|
||||||
return l * r;
|
r *= 2 - d * r;
|
||||||
|
return l * r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mulDiv(
|
function mulDiv(
|
||||||
@ -35,15 +39,19 @@ library FullMath {
|
|||||||
uint256 y,
|
uint256 y,
|
||||||
uint256 d
|
uint256 d
|
||||||
) internal pure returns (uint256) {
|
) internal pure returns (uint256) {
|
||||||
(uint256 l, uint256 h) = fullMul(x, y);
|
if (d == 0) revert("FullMath: DIVISION_BY_ZERO");
|
||||||
|
|
||||||
uint256 mm = mulmod(x, y, d);
|
unchecked {
|
||||||
if (mm > l) h -= 1;
|
(uint256 l, uint256 h) = fullMul(x, y);
|
||||||
l -= mm;
|
uint256 mm = mulmod(x, y, d);
|
||||||
|
|
||||||
if (h == 0) return l / d;
|
if (mm > l) h -= 1;
|
||||||
|
l -= mm;
|
||||||
|
|
||||||
require(h < d, "FullMath: FULLDIV_OVERFLOW");
|
if (h == 0) return l / d;
|
||||||
return fullDiv(l, h, d);
|
|
||||||
|
require(h < d, "FullMath: FULLDIV_OVERFLOW");
|
||||||
|
return fullDiv(l, h, d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user