Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

C# has a decimal type: "The decimal type is a 128-bit data type suitable for financial and monetary calculations." https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...


That provides the basis for solving precision and rounding issues but for a money library you need more abstractions. The ability to assign a currency code and supply conversion rates and convert between currencies at a minimum.


Also, avoid making errors like summing different currencies.


The thing is, it doesn’t really help. A system I’m working on can have hundreds of monetary amounts in the same currency. Storing the currency against each one is an awful waste of space.

Equally the allocation trick is good, but you’ll find that the people who really care about this stuff really care about the exact algorithm you’re using and who it favours.


I think it helps to have the inputs and outputs of the system fully representing a "money" (i.e., a monetary amount + its currency code in places like API resources, events, and so on). This way you can internationalize or support multi-currency processing if that's the case. That's (if I remember correctly) what the payment card services companies (e.g., Mastercard, Visa) do by default in their message exchanges when calling the issuer for transaction confirmation.

Anyway, the allocation may be tweaked to favour where the additional/missing pennies will be allocated. You can find more at: https://github.com/eriksencosta/money/blob/trunk/docs/usage/...


That’s an application design choice, not a minimum. An alternative is to work internally in one unit and convert at format time.


We store all our financial data in Greenwich Mean Dollars.


What are you going to do about the new Moon Dollars?


Might be a minimum for a money library (not completely sure what the absolute minimum would be). It would be an application design choice to not use one and stick to general fixed point/Big Num constructs.


That is not a viable alternative.


Even though my gut reaction is to agree with you, it’s true that it is an app design decision, so in certain scenarios it might very well be a good design decision.


Shipped applications disagree with you.


It really depends on the context of the app

Sometimes you can do all calculations in a single currency and convert at reporting time. I've worked on teams where that was fine.

Sometimes... you really cannot do that.


Completely agree.


Out of curiosity, how do you deal with changing exchange rates in that case?


You never want to be lossy with user inputs. Save what they told you and then convert for internal logic.

The OP just described a language feature where you want to multiply euros with usd one place and yen and dinar in another.

You don’t need to do that which is why a decimal or 64 bit int is a fine language approach.


it depends, if it was a currency exchange, it'll be labeled in one of 3 ways, either average rate per unit, absolute, or it'll be a reference to a MSSQL table containing exceptional spot transactions. Otherwise, a complete history of exchange rates is stored in KDB, most days you can take the average, and for small amounts on weekends or days the exchange is closed you can just interpolate, there's also a half dozen XLSXs full of certain exceptional days, so you'll have to check that you're not on one of those lists. Then if you're not dealing with USD->X or CAD->USD->X things start to get hairy.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: