We've received multiple requests for a fixed point math library in OpenZeppelin (e.g. here). For those that are not familir with this concept, it basically boils down to scaling an integer so that a certain (fixed) number of decimals are included, e.g. a value of 100 would represent the number 1.00 if using two decimals, and multiplying 100 by 200 would yield 200 (1.00 * 2.00 = 2.00
). This is particularly useful when dealing with decimals on systems that have no floating point support, but allow for large integers (e.g. on 32-bit microcontrollers, and especially on the EVM). You can read more about it here.
Given that fixed-point arithmetic is quite a low-level primitive, I don't think we should aim for full-fledged support, since the potential for misuse is quite large due to the unfamiliarity of developers with this concept, and the difficulty of handling different number types without getting them mixed up (e.g. regular integers and custom fixed-point representations).
Because of this, and given that the usefulness of fixed-point support in the context of Ethereum usually comes from a need to calculate fractions of values (like in PaymentSplitter
here), I propose implementing a simpler, easier-to-use library, where the only supported operation is calculating a percentage of a number, i.e. answering questions such as 'how much is 75.6% of x
?'.
This could be done in a number of ways, e.g. with a function that receives a regular integer and a percentage number (scaled by some factor so that decimals are included - a percentage of 5000 could stand for 50.00%, 5023 for 50.23%, etc.), and returns both the requested fraction and the remainder, which may be useful to avoid leftovers (e.g. if a value is split into three fractions of 33.33%, 0.01% will be left unclaimed) - thanks @frangio for this suggestion!
I'd love to hear everyone's thoughts about this!