I want to calculate a mathematical function which will use the mathematical constant e, and I don't know how to use e, like Math.e
.
Solidity doesn't support floating-point arithmetic.
You'll need to represent e
with a pair of an integer numerator and an integer denominator.
For example:
uint256 eN = 271828;
uint256 eD = 100000;
Then, you'll need to replace every plan for x * e
in your code with x * eN / eD
.
In order to achieve maximum accuracy while reducing the number of erroneous computations to minimum, set the highest possible value of eN
(and then set eD
accordingly), such that maxX * eN
in your program is smaller than 2 ^ 256.
Also for maximum accuracy, keep in mind that you should try to postpone the / eD
part as much as possible.
For example, change x * eN / eD + y
to (x * eN + y * eD) / eD
.
Of course, the condition of maxX * eN
being smaller than 2 ^ 256 changes to x * eN + y * eD
being smaller than 2 ^ 256.
Alternatively to all of that, you can replace every x * y
in your code with x.mul(y)
(see an example implementation of function mul
in OpenZeppelin's SafeMath Library).
But beware that this will:
- Replace every erroneous computation with the transaction being reverted
- Increase the gas cost of every computation which makes use of multiplication
Here is a short Python 3 snippet for the "offline" calculation of eN
and eD
given maxX
:
from decimal import Decimal
from decimal import getcontext
getcontext().prec = 100
def getBestE(maxX):
e = Decimal(1).exp()
eD = int((2**256-1)/(e*maxX))
eN = int(eD*e)
return eN,eD
You can run it once, and then define those two constants in your code.
Of course, you can use different pairs of eN
and eD
for different computations (it's all a question of how "dirty" you're willing your code to be in favor of optimizing accuracy and/or performance).
-
Thank you for your answer, it completely solved my question.This is the first time that i post a question, and get a very complete solution, it feels me so good.Finally wish you have fun in your life – user6391810 Mar 18 '20 at 3:33
-
@user6391810: Hahaha. Thank you, glad you've enjoyed the answer :) – goodvibration Mar 18 '20 at 6:35