-
Notifications
You must be signed in to change notification settings - Fork 11.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add sqrt for math #3242
Add sqrt for math #3242
Conversation
Thanks @jjz. Some things we want to do before merging:
|
I don't know what kind of evaluation is needed, because this method is |
The version in #3282 is simpler (no special case, but has the drawback of overflowing for
This can be fixed by doing
I suggest we use that version. |
Gas costs are worryingly high. Finding the |
PRB has a version with constant cost IMO this would be much better. It's a bit more expensive for small values, but it is orders of magnitude cheaper for big values. |
contracts/utils/math/Math.sol
Outdated
@@ -149,4 +149,62 @@ library Math { | |||
} | |||
return result; | |||
} | |||
|
|||
/** | |||
* @dev Returns the square root of a number. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only the case for perfect squares, we should document the behavior for the other numbers. I suppose it rounds down.
Does it make sense (is it possible?) to provide a version with a Rounding
argument?
Do you think we can document some aspect of the efficiency of this function? It's O(1) but can we say anything stronger in terms of the constants involved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a version with Rounding
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we could provide an upper bound on the gas cost, I'm not sure what else we can say
contracts/utils/math/Math.sol
Outdated
// of the bits. the partial result produced is a power of two that verifies `result <= sqrt(a) < 2 * result` | ||
uint256 result = 1; | ||
uint256 x = a; | ||
if (x > 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would write this like this, otherwise we basically need to count F
s to know if the code is right.
if (x > (1 << 128) - 1) {
The compiler seems to optimize this expression to a constant, even when optimizations are disabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
then what about doing x >= 1 << 128
. Would that also get optimized? to the same bytecode. Because there is no gte
opcode I'm worried it would be compiled to not(lt(..., ...))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I found an even better rewording.
contracts/utils/math/Math.sol
Outdated
// For our first guess, we use the log2 of the square root. We do that by shifting `a` and only counting half | ||
// of the bits. the partial result produced is a power of two that verifies `result <= sqrt(a) < 2 * result` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is clear or accurate.
For our first guess, we use the log2 of the square root.
What does it mean that we "use the log2"? I read this like saying that our guess is log2(sqrt(a))
, but I don't think this is true.
I also find the part about shifting a
confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me.
Fixes #3149
When we use SWAP, we often need to use the
sqrt
operation, which is not in Math, so I added it.https://github.com/Uniswap/v2-core/blob/4dd59067c76dea4a0e8e4bfdda41877a6b16dedc/contracts/UniswapV2Pair.sol#L95
PR Checklist