15

Solidity doesn't have fixed-point, floating-point, or double types. What solutions are there to handle the cases where we really have to represent numbers as percentages or fractions?

Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143

1 Answers1

27

Disclaimer: I am the author of PRBMath.

Fixed-Point

  1. PRBMath
    • signed and unsigned denary numbers with 18 decimals of precisions
    • offers advanced math functions (logs, exp, pow, etc.)
    • provides type safety via user defined value types
    • gas efficient, but still user-friendly
    • ergonomic developer experience thanks to using free functions instead of libraries
  2. ABDKMath64x64
    • binary numbers with 2^64 precision
    • offers advanced math functions (logs, exp, pow, etc.)
    • ultra gas efficient (see this praise)
  3. Fixidity
    • denary numbers with arbitrary number of decimals
    • offers advanced math functions (logs, exp, pow, etc.)
    • slower than 64.64, but with a more palatable API
    • used by CementDAO, PoolTogether and Celo
  4. Exponential
    • denary numbers with 18 decimals of precision
    • minimal features, doesn't offer advanced math functions
    • developed by Compound.Finance
  5. DecimalMath
    • denary numbers with 27 decimals of precision
    • minimal features, doesn't offer advanced math functions
    • uses ABIEncoderV2 (experimental in Solidity 0.7 and below)
  6. DSMath
    • denary numbers with 18 (WAD) and 27 decimals of precision (RAY)
    • minimal features, doesn't offer advanced math functions
    • developed by the DappHub team, used by the Maker protocol

Floating-Point

  1. ABDKMathQuad
    • developed by the same company as 64.64
  2. Bankex
    • IEEE-754 octuple precision floating-point

Addenda

  1. There's an open issue in the solidity repo for adding native support for fixed-point types
  2. Mikhail Vladimirov's Math in Solidity blog series is a fantastic resource to learn about how advanced math functions can be implemented in Solidity v0.6 and lower
  3. There are more math libraries mentioned in this OpenZeppelin forum post
Paul Razvan Berg
  • 17,902
  • 6
  • 73
  • 143
  • 1
    You forgot the simplest (and most accurate) method: maintain a tuple of numerator and denominator, and in every computation, avoid division for as long as possible (i.e., use it only in order to avoid an overflow). – goodvibration May 27 '20 at 20:32
  • 1
    That's true, but I'd argue that the simplest approach to fixed-point math in solidity is also the brittlest. – Paul Razvan Berg May 27 '20 at 20:39
  • 1
    I had to google-translate brittlest, which gave me: having hardness and rigidity but little tensile strength. Now I have to google-translate pretty much every one of the words in that... – goodvibration May 27 '20 at 20:52
  • 2
    Hah, what I meant is, I wouldn't encourage a simple approach when dealing with fixed-points. There's always something that could go wrong, and I'd rather rely on other more robust contracts (and tests!) that people wrote before me. – Paul Razvan Berg May 27 '20 at 20:54