0

In Solidity division of uint256 rounds down the value. Let's say I want to issue some token amount based on duration like this:

uint256 MAX_TIME = 365 days;
uint256 Duration1 = 223 days;
uint256 Duration2 = 142 days;
uint256 amount = 100e18; 

uint256 amount1 = amount.mul(Duration1).div(MAX_TIME); 
uint256 amount2 = amount.mul(Duration2).div(MAX_TIME); 

What I want is to be able to calculate the initial amount by converting and adding amount1 and amount2. This solution does not work because amount1 and amount2 were rounded above:

uint back = amount1.mul(MAX_TIME).div(Duration1) + amount2.mul(MAX_TIME).div(Duration2);

I tried adding precision to save the fractional part:

uint256 PRECISION = 1e18;

uint256 amount1 = amount.mul(Duration1).mul(PRECISION).div(MAX_TIME); 
uint256 amount2 = amount.mul(Duration2).mul(PRECISION).div(MAX_TIME); 

// Back to amount
uint256 back =  amount1.mul(MAX_TIME).div(Duration1).div(PRECISION) + amount2.mul(MAX_TIME).div(Duration2).div(PRECISION);

But that way I also don't get the correct initial amount. Is there a way to get the initial amount and what tools can I use? Or is it simply not possible because of the math?

1 Answer 1

0

In fact, even in other languages, you wouldn't get the correct amount. Math in computers won't allow you to because the computers represent the number in a discrete way, with a certain amount of binary digits. So there will always be some portion of imprecision.

Though what you may do in Solidity (unlike many other languages because Solidity supports the integers up to 256 bits in size and always deals with them instead of floating numbers) is to save the remainder before each divide operation and then add up it too when you need to get the full amount. The modulo operator in Solidity

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.