4

I would like to do some basic operations in the runtime like:

let new_balance = .5 * old_balance;

Or save a percentage value in the runtime storage.

Or represent the balance of a user like: 3.141592 TOKENS

How can I do these kinds of things? Am I allowed to use floating point numbers in the runtime?

2 Answers 2

13

You cannot use floating point math inside of the runtime.

Floating point numbers can lead to non-determinism in computer systems, and that would be exceptionally bad for blockchains since all of them must come to consensus.

Instead, you must make sure to use fixed-point arithmetic within the entire runtime environment, and Substrate even provides tools to help you with this in the crate sp_arithmetic.

So to answer these specific scenarios:

  • Consider dividing by 2 rather than multiplying by .5.
let new_balance = old_balance / 2;
  • Use the Percent type or some of the other per_thing types which behave like a standard percentage, but use fixed point math under the covers.

  • Use a fixed point number.

In Substrate, user balances are normally represented with a u128. However, to express these balances in "human form" a fixed point decimal is used. So while a user's real balance as a u128 would be something like 3_141_592_000_000 UNITS, we would represent it in the UI by first dividing by 10^12, and displaying it as 3.141592 TOKENS. Assuming your fixed point decimal is 12. However different networks may make different choices how many decimal places to use.

This decision is arbitrary.

1
  • 1
    Is it possible to use sp_arithmetic in ink contracts?
    – forgetso
    Commented Apr 25, 2022 at 13:53
1

Sometimes, sp-arithmetic can not fit your requirement.

Please also take a look at the substrate-fixed.

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.