25

I just started writing some solidity and I noticed that there are no decimal values such as double or float.

What do you guys do when you need to return send to a wallet let's say 1.57 ether? Or when you need to calculate 1/2 = 0.5?

I'm very confused - I tried doing something like var a = 0.5; but it gives me an error that says

Invalid literal value.

23

Math in Solidity is done entirely using fixed-point. For ether, there's no need to use fractional values - all values are represented in wei, which is the smallest unit of ether.

If you want to send 0.5 ether, you can instead specify your literal as "500 finney", which will be converted into wei:

msg.sender.send(500 finney);

or:

msg.sender.send(1 ether / 2);

which are both exactly equivalent to:

msg.sender.send(500000000000000000);

If you want to multiply a value by a fraction (eg, 2/3), first multiply by the numerator, then divide by the denominator:

value = (value * 2) / 3;

It's worth noting, too, that floating point for financial math is a terrible idea - it introduces rounding errors that easily lead to lost money.

  • 1
    @NickJohnson Let me ask you just one more thing. So when a wallet sends funds to a contract, if I call the msg.value function? This will return me the amount of ether represented in wei right? So by default in the contract I'm always talking about wei? – sfrj Apr 14 '16 at 16:02
  • 2
    @sfrj That's right. – Nick Johnson Apr 14 '16 at 16:11
4

The Fixed Point Numbers documentation has a warning which says:

Fixed point numbers are not fully supported by Solidity yet. They can be declared, but cannot be assigned to or from.

The warning at the bottom of Rational and Integer Literals says:

Division on integer literals used to truncate in earlier versions, but it will now convert into a rational number, i.e. 5 / 2 is not equal to 2, but to 2.5

  • 2
    So what can you do with them if they can't be assigned to or from? – Justin Harris Jul 4 '18 at 22:48
3

There is a mention of Reals as a value type in the Solidity documentation.

Edit: It was actually the old documentation, on Github. No mention in the ReadTheDocs-documentation.

Reals are formed similar to integers except that they include a decimal point and at least one number on either side of it. An example would be: 3.14159265 and 42.000001.

I get compiler errors when attempting to use these, so they might not be implemented yet.

0

For 1.57 ETH, note that in Ethereum all Ether amount are measured in Wei, and 1 Ether is just 10^18 Wei, so 1.57 ETH is basically 1570000000000000000 Wei, i.e. integer number.

For 1/2 = 0.5 you probably need some kind of fixed point library, such as ABDK Math 64.64. It operates with binary fixed point numbers (64 binary digits after dot) and has all basic math operations.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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