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?
1 Answer
Disclaimer: I am the author of PRBMath.
Fixed-Point
- 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
- ABDKMath64x64
- binary numbers with 2^64 precision
- offers advanced math functions (logs, exp, pow, etc.)
- ultra gas efficient (see this praise)
- 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
- Exponential
- denary numbers with 18 decimals of precision
- minimal features, doesn't offer advanced math functions
- developed by Compound.Finance
- 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)
- DSMath
Floating-Point
- ABDKMathQuad
- developed by the same company as 64.64
- Bankex
- IEEE-754 octuple precision floating-point
Addenda
- There's an open issue in the solidity repo for adding native support for fixed-point types
- 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
- There are more math libraries mentioned in this OpenZeppelin forum post
-
1You 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). Commented May 27, 2020 at 20:32
-
1That's true, but I'd argue that the simplest approach to fixed-point math in solidity is also the brittlest. Commented May 27, 2020 at 20:39
-
1I 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... Commented May 27, 2020 at 20:52 -
2Hah, 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. Commented May 27, 2020 at 20:54