Dealing With Decimals In Smart Contracts

In cryptography, we often use unsigned integers, and never have much to do within floating-point values. But, obviously, we need…

Photo by Chris Liverani on Unsplash

Dealing With Decimals In Smart Contracts

In cryptography, we often use unsigned integers, and never have much to do within floating-point values. But, obviously, we need floating-point values for many of our calculations, such as for calculating compound interest in a financial contract or computing the area of a circle. And, so, if we need to implement decimal operations in our smart contracts, we need the addition of code that processes decimal values but uses integer operations.

The basics of decimal operations

So let’s see how we can perform maths operating using decimal values. For example, some simple calculations are:

6.1 + 5.2 = 11.3
6.1 * 5.2 = 31.72
6.1 - 5.2 = 0.9
6.1 / 5.2 = 1.173
1/6.1 = 0.1639

One method of supporting decimals is basically to move the decimal point so that the value looks like an integer. For example, 6.546 could be 6546 and 3.134 could be 3134, and where we move three decimal places. As long as we remember how many places we move the decimal point, we can reverse the operations. And so adding is easy:

6546 + 3134 = 9679

and, as we have shifted by three decimal places we get 9.679. When we multiply we get:

6546 *3134 = 20512030

This time, because we are multiplying we need to move the number of decimal places by twice the amount moved (as you may remember from school), and so we get:

20.512030

With a divide, we take the reciprocal on the divisor and then multiply it.

Fixed-point decimals

There are a range of libraries we can use for our smart contracts, such as ABDK and fixidity. In this case we will use fixidity [here], and which moves the comma 24 digits. For the value of 1 we get:

1000000000000000000000000

and where we get 24 decimal places, and then the whole part. So, the best way to try this is we some Solidity code:

We first enter our code in Remix [https://remix.ethereum.org]:

Next, we can run our local blockchain (with ganache), and then deploy our smart contract:

We can see that the address that has deployed the smart contract has been charged some ether to mine it. Next, we can test it.

The answer is: 11300000000000000000000000. If you count 24 places for the decimal point we get: 11.300000000000000000000000, and which is the right answer for 6.1 + 5.2.

Now let’s try subtract (a-b) and reciprocal (1/x):

For subtract, we get: 900000000000000000000000 and which is 0.900000000000000000000000 (when we move by 24 decimal places). Again, this is correct for 6.1–5.2.

For the reciprocal, we have implemented 1 divided by 6.1. We can see the answer is 163934426229508196721311 and when we move 24 decimal places we get 0.163934426229508196721311.

Now let’s multiply 6.1 and 5.2:

For multiply, we get: 31720000000000000000000000 and, when we move 24 decimal places we get 31.720000000000000000000000. Finally, we will divide:

For divide, we get: 1173076923076853846153842 and — when we move by 24 decimal places, is: 1.173076923076853846153842. This again is the correct answer for 6.1/5.2. The library will also give us the fractional part of the number, such as for 6.1:

and which is 0.1 in a decimal form.

And that’s it! Welcome to the wonderful world of smart contacts.