# How Do You Calculate Compound Interest in Solidity?

I know that Solidity doesn't use decimals, but I'm having a hard time wrapping my head around 18 zeros in Wei in calculating compound interest. How do you do it? I have found no examples.

I first tried this:

``````contract CompoundInterest {

uint public Periods = 30;
uint public Principle = 10000;
uint public Interest;
uint public InterestRateInteger = 2;

function CalculatedInterest() public {

Interest = Principle * (1 + InterestRateInteger/100)**Periods;

}
``````

This example is just the classic compound interest formula. I tried this as well, and got a result that was correct, but I couldn't figure out how to refactor for Wei.

`````` function CalculatedInterest() public {

Interest = Principle * (100 + InterestRateInteger)**Periods;

}
``````

The idea is that interest only compounds years, so 102 would be equal to 1.02.

Using a for loop works, but I'm not sure if this is optimal:

`````` for (i=0;i<Periods;i++) {
Principle += Principle* InterestRateInteger/100;

}
``````

See this answer for a much faster solution, independent of the number of periods: Is there any efficient way to compute the exponentiation of a fraction and an integer? Copied from the answer:

The following is a decent, low-cost approximation:

``````// Computes `k * (1+1/q) ^ N`, with precision `p`. The higher
// the precision, the higher the gas cost. It should be
// something around the log of `n`. When `p == n`, the
// precision is absolute (sans possible integer overflows). <edit: NOT true, see comments>
// Much smaller values are sufficient to get a great approximation.
function fracExp(uint k, uint q, uint n, uint p) returns (uint) {
uint s = 0;
uint N = 1;
uint B = 1;
for (uint i = 0; i < p; ++i){
s += k * N / B / (q**i);
N  = N * (n-i);
B  = B * (i+1);
}
return s;
}
``````

This function computes `k * (1+1/q) ^ N`. So, for example, to compute `2500 * 1.01 ^ 137`, we could use `fracExp(2500, 100, 137, 8)`. This outputs `9769`, which is very close to the real value, `9771.657061221898`.