First off - not the same question as this (which is great). I need the exponent to be fractional as well. Something like 2.5^0.75

  • @MaiaVictor Im adding a bounty for anyone who can come up with something here. Note: The Bancor equations most likely need this as well for their connector-weight exponent
    – ZMitton
    Commented Jun 6, 2018 at 15:32
  • 2
    Well you can read how bancor done this in their smart contract - github.com/bancorprotocol/contracts/blob/master/solidity/…
    – leonprou
    Commented Jun 11, 2018 at 13:14
  • this is good. I've asked the author to explain how it works
    – ZMitton
    Commented Jun 11, 2018 at 17:14
  • You can see how it's done in C also - stackoverflow.com/questions/24174239/…. It looks somewhat alike.
    – leonprou
    Commented Jun 12, 2018 at 7:38
  • @ZMitton damn I wasn't notified. A little bit late. Glad you found a solution!
    – MaiaVictor
    Commented Jun 12, 2022 at 10:12

2 Answers 2


The code of a good solution:

function power(uint256 _baseN, uint256 _baseD, uint32 _expN, uint32 _expD) internal view returns (uint256, uint8) {
    assert(_baseN < MAX_NUM);

    uint256 baseLog;
    uint256 base = _baseN * FIXED_1 / _baseD;
    if (base < OPT_LOG_MAX_VAL) {
        baseLog = optimalLog(base);
    else {
        baseLog = generalLog(base);

    uint256 baseLogTimesExp = baseLog * _expN / _expD;
    if (baseLogTimesExp < OPT_EXP_MAX_VAL) {
        return (optimalExp(baseLogTimesExp), MAX_PRECISION);
    else {
        uint8 precision = findPositionInMaxExpArray(baseLogTimesExp);
        return (generalExp(baseLogTimesExp >> (MAX_PRECISION - precision), precision), precision);

Full working code at: https://github.com/Muhammad-Altabba/solidity-toolbox/blob/master/contracts/FractionalExponents.sol

Some explanation

A floating point number x can be represented in two numbers: a/b

 if x = a/b and y = c/d, then x ^ y = (a/b) ^ (c/d)

The problem

The problem is that if the a code is written as (a/b) ^ (c/d), the accuracy of the result would be a mess. Because the division of a/b and c/d would smash the floating point.

Going into another try, the expression (a/b) ^ (c/d) could be evaluated as a ^ (c/d) / b ^ (c/d) or (a^c + a^(1/d)) / (b^c + b^(1/d)). The problem with this is that the powering a to c or even to c/d could easily overflow uint256! Even though, the final resulting value could be a small uint8. (this is explained here)

The Solution

There is an approximation for x ^ y as follow:

x ^ y  = e ^ (log(x) * y)

Actually, the method above depend on this equation to compute the power function. As follow:

(_baseN / _baseD) ^ (_expN /_expD) = e ^ (log(base) * exp)

Where base = _baseN / _baseD (note that FIXEX_1 that is used in the code, is just used to shift the number of left in order to provide better accuracy of the division. And exp = _expN /_expD.

The key point here is calculating the log(base) * exp before powering to e, will prevent overflow compared to the early discussed formula the can easily produce overflow: a ^ (c/d) / b ^ (c/d) or (a^c + a^(1/d)) / (b^c + b^(1/d)).

However, for optimalLog vs. generalLog and optimalExp vs. generalExp that is used in the provided code, they is about calculating the log and e ^ either in an optimal or an approximate calculation.

Thanks leonprou for his valuable comments on the question.

  • I gave you the check mark but you've removed some of the functions. Could you please include those so that this compiles?
    – ZMitton
    Commented Jun 20, 2018 at 16:11
  • 1
    I did not include the full code in the answer because it is quite long with 350+ lines of code. However, upon your request I created a file that contains only and all the needed functions at github.com/Muhammad-Altabba/solidity-toolbox/blob/master/… . Commented Jun 20, 2018 at 18:23

You may calculate x^y as 2^(y log_2 x) using ABDK Math 64.64 library, that has both: 2^x and log_2 x functions implemented for binary fixed point numbers. This way is especially efficient in case you need to calculate x^y multiple times for the same x but different y, because you may calculate log_2 x once and reuse.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.