socialpredict
socialpredict copied to clipboard
Integer Based Betting Amounts
Writing and explanation on keeping track and using integers for Prediction Markets:
https://money.dpldocs.info/v3.0.2/money.html
From package:
https://code.dlang.org/packages/money
Handling amounts of money safely and efficiently.
An amount of money is a number tagged with a currency id like "EUR" or "USD". Precision and rounding mode can be chosen as template parameters.
If you write code which handles money, you have to choose a data type for it. Out of the box, D offers you floating point, integer, and std.bigint. All of these have their problems.
Floating point is inherently imprecise. If your dollar numbers become too big, then you start getting too much or too little cents. This is not acceptable as the errors accumulate. Also, floating point has values like "infinity" and "not a number" and if those show up, usually things break, if you did not prepare for it. Debugging then means to work backwards how this happened, which is tedious and hard.
Integer numbers do not suffer from imprecision, but they can not represent numbers as big as floating point. Worse, if your numbers become too big, then your CPU silently wraps them into negative numbers. Like the imprecision with floating point, your data is now corrupted without anyone noticing it yet. Also, fixed point arithmetic with integers is easy to get wrong and you need a fractional part to represent cents, for example.
As a third option, there is std.bigint, which provides numbers with arbitrary precision. Like floating point, the arithmetic is easy. Like integer, precision is fine. The downside is performance. Nevertheless, from the three options, this is the most safe one.
Can we do even better? If we design a custom data type for money, we can improve safety even more. For example, certain arithmetics can be forbidden. What does it mean to multiply two money amounts, for example? There is no such thing as $² which makes any sense. However, you can certainly multiply a money amount with a unitless number. A custom data type can precisely allow and forbid this operations.
Here the design decision is to use an integer for the internal representation. This limits the amounts you can use. For example, if you decide to use 4 digits behind the comma, the maximum number is 922,337,203,685,477.5807 or roughly 922 trillion. The US debt is currently in the trillions, so there are certainly cases where this representation is not applicable. However, we can check overflow, so if it happens, you get an exception thrown and notice it right away. The upside of using an integer is performance and a deterministic arithmetic all programmers are familiar with.
Further to this issue, we should use int or int64 rather than uint. Re:
https://stackoverflow.com/questions/63105394/in-go-when-should-you-use-uint-vs-int
Using uint is only saving us one bit for every entry, we probably don't need it.
the minimum value of the int64 type, is -9,223,372,036,854,775,808 use the math.MinInt64 constant.
maximum value of the int64 type, which is 9,223,372,036,854,775,807, use the math.MaxInt64
E.g. 9.2*10^18 or 9 quintillion.
Total global money supply in USD is around 100 trillion in 2022 or 10010^12, 110^14, or one Quattuordecillion so we are still around 4 orders of magnitude off.