5 ms·
> There are no floating point numbers. Since you're probably working with "money", this can make things tricky. That is actually a feature when it comes to wor
by Slartie 9y ago
> There are no floating point numbers. Since you're probably working with "money", this can make things tricky.
That is actually a feature when it comes to working with money. You don't ever want to use floating-point arithmetic with monetary values due to its inability to represent all possible decimal fractions of your base unit. This is just as true for over-hyped blockchain stuff as it is for any imaginable application in the "classic" financial sector.
What you need is either an integer data type plus a fixed, implied number of digits that you want to handle (so for example 105 represents 1 dollar and 5 cents), or a fixed-point numeric type (like for example BigDecimal in Java; there's lots of equivalents in other languages, most of them have something like "decimal" in their names), which essentially just stores the integer value together with the number of digits and features mathematical operations of pairs of these with each other.
- jackpeterfletch 9y agoTrue, but the extra code around those solutions cost gas, of which your looking at around 500 lines worth. How long is BigDecimal.class?
- SanFranManDan 9y agoLikely you don't need a generic implementation of Decimal. What money do you want to represent, they all have a "atomic value". For instance, when working with dollars store cents. When working with Eth, store wei. etc. I can't think of a use case of money that needs decimals except maybe computing ownerships percentage. but that should never be stored, but rather computed. Anything that needs to be converted is a "front end" view. all computations should use atomic store of value, thus no conversion is needed in contracts.
- aquadrop 9y agoYou might need to work with fractions of "atomic values" to get the desired level of accuracy. So you have to store not logical cents, but 1/100th of cents or something like that. Much easier and straightforward just use decimal-like type.
- jackpeterfletch 9y agoYep, when doing financial stuff, those half cents can count.
- mbrock 9y agoThat's what happens in e.g. the Maker stablecoin project. Decimal fixed point to give sub-wei precision when prorating per-second compounding fees. Other than the normal simple arithmetic operations, we use "exponentiation by squaring" to take a decimal fixed point raised to an integer power.
- dragonwriter 9y ago> What money do you want to represent, they all have a "atomic value". This is mostly not true. > For instance, when working with dollars store cents. While external transactions often must occur in cents, internal accounts and unit prices often have smaller amounts. If you don't believe me, visit any US gas station and the prices will be in mils, not cents (and will usually be one mil less than some full-cent value per gallon.) Atomic units for financial applications are application-specific if there is an appropriate value at all, they aren't trivially determinable by looking at the base currency. In some cases you really want an arbitrary precision decimal (or even rational) representation.
- alasdair_ 9y ago>For instance, when working with dollars store cents. How does this work of you are, say, coding for a gas station where the price is in 1/10ths of a cent? Alternatively, how does your banking application handle adding 10% interest to a bank account with 1c in it?
- Slartie 9y agoProviding a decimal type would of course not be the job of the developer of a smart contract - I would expect that the smart contract platform would anticipate the necessity of convenient decimal number handling and thus provide a suitable abstraction. In the case of Ethereum, it could either be provided in the language or on the virtual machine level. I'm not that much into the EVM's inner workings to judge whether a machine-level implementation would be a good idea from an architectural viewpoint, but it would definitely deliver the best possible performance and lead to the smallest amount of contract code, thereby saving on gas to deploy the contract. As a second-best solution, the language could provide such an abstraction - it would at least be able to apply optimizations when compiling the code down to EVM opcodes, which an implementation purely on the contract level would not be able to do.
- monocasa 9y agoEVM is a 256-bit architecture, so it probably doesn't a BigDecimal equivalent for financial transactions.
- Kranar 9y ago>That is actually a feature when it comes to working with money. You don't ever want to use floating-point arithmetic with monetary values due to its inability to represent all possible decimal fractions of your base unit. This is just as true for over-hyped blockchain stuff as it is for any imaginable application in the "classic" financial sector. I feel like this is constantly repeated but is simply untrue and working in the financial sector (high frequency trading) I don't know anyone who actually uses fixed digit number systems to represent money. Normally what I do see are people outside of finance who need to represent money who read the common mantra about using a fixed digit representation only to eventually encounter all the issues that floating point was invented to solve. When they encounter those issues they then end up having to adapt their code only to basically re-invent a broken, unstable quasi-floating point system when they would have been much better off using the IEEE floating point system and actually taking the time to understanding how it works. BigDecimal will solve the issue but it's absolute overkill both in terms of space and time, we're talking many many orders of magnitude in terms of performance degradation and it's entirely unneeded. One simple solution that works very well for up to 6 decimal places is to take your idea of having an implied number of digits, but instead of using an integer data type, you use a floating point data type. So 1 dollar and 5 cents becomes (double)(1050000.0). This lets you represent a range from 0.000001 up to 9999999999.999999 exactly, without any loss of precision. Values outside of that range can still be represented as well but you may have some precision issues. Another solution which is less efficient but more flexible is to use decimal floating point numbers instead of binary floating point numbers. There is an IEEE decimal floating point standard that can represent an enormous range of decimal values exactly. Intel even provides a C/C++ implementation that meets formal accounting standards. Both of the solutions I list above are orders of magnitude more efficient than using fixed-point numeric types and are by no means difficult to use.
- Slartie 9y agoSelf-quote: > any imaginable application in the "classic" financial sector Kranar: > working in the financial sector (high frequency trading) Okay, you got me there - you have pointed me to that single application from the financial sector where it is not totally acceptable to "waste" a few thousands of processor cycles to compute some money-related stuff. Granted, in HFT applications, these cycles may allow you to get your trades in front of those of the other HFT companies. You are forced to use CPU-accelerated (or maybe even GPU?) computations in this case, which automatically means "floating point". But there's another difference that allows you do do this: you mostly don't have to care about exact, accurate-up-to-the-penny results. I assume most of your calculations are done to eventually arrive at a conclusion of whether to buy or sell some stock or not, and at which price. You have to take care of not accumulating too much rounding errors in the process, of course, but the threshold for these errors is set by yourself, and you can give yourself a bit of leeway on this, because it's all internal stuff, mostly probabilistic and statistics-based - the only stuff that may be audited by someone else and thus has to match the real numbers up to the last penny are the trades you do and the money you move around, and I bet all of this accounting-style stuff is recorded using...decimal numbers :D I work in the retail industry (think cash registers, retail sale accounting, that kind of stuff) and pretty much any legislation on this planet would obliterate us if we'd tell them that the result of the computations of our systems may be some cents up or down from the real result - the one someone would get who just scribbled the numbers on a sheet of paper and added them up manually. Our customers have to pay taxes based on the sales that they account using our systems, and the tax calculations as well as the entire chain of processes they use to arrive at the final numbers are regularly audited by the respective governments. There are specific rules (of course differing by country) as to how many decimal places have to be used and how stuff has to be rounded in which particular cases in calculations that would require more decimals. We waste an enormous amount of CPU cycles just to strictly adhere to these rules - and that is not only absolutely necessary, but also totally okay, modern CPUs can easily accomodate this in our scenario.
- bkcreate 9y agoI think a good system to look at copying in the real world is the Czech Koruna or Japanese Yen. It is a real world example of a currency that doesn't use decimal values. This simplifies the math involved and by having each unit have a very small value you can replace cents, and you don't have money "dissapear" due to being rounded off.