CharlesO

CharlesO

Built in datatype for handling money values?

It would be nice to have a built in datatype for handling money values.

Most currency activities are exactly two decimal places.

Such a built-in convenience would be more helpful that requiring the decimal library, for example since all we need is 100.00 or 2-decimal place accuracy at most.

Please what suggestions do you have? or should we just be using floats for this, since the required precision is exactly 2 decimal places.

Marked As Solved

OvermindDL1

OvermindDL1

Using a protocol, say via @Qqwy’s number library, you could easily just redefine + to call it’s protocol dispatched add function, then it would just work with, say, Decimal.

Something like 100.00 + 10 is ill defined though, I hate hate hate it when languages allow it. Do you want it to be 110.00 or do you want it to be 110 or do you want it to come out as some new type or etc… etc… That is why I like statically strongly typed languages making both operands to + be the same type, that way it is properly formed.

Also Liked

kip

kip

ex_cldr Core Team

According to the data I have there are:

  • 52 currencies that have no decimal places
  • 239 that have 2 decimal places
  • 3 that have 3 decimal places
  • 1 that has four decimal places

But you should also consider that some currencies have specific rounding rules for cash values that relate to the physical currency in circulation.

For example, the AUD and CHF have cash rounding to 0.05 but normal rounding to 0.01.

Additionally there is the question as to when to round and to what precision. In a chain of financial transactions it is most common (according to my research, not an formal statement) that rounding is performed only at the end of the chain.

Then if you are splitting up money (like allocating it to various amounts) then rounding has to be handled carefully to ensure that any remainder is taken care of.

Anyway, money handling and its implication in the real world is an interesting problem - but its not just about decimal arithmetic (I am the author of ex_money and suggestions and PRs are always welcome)

kip

kip

ex_cldr Core Team

100.00 + 10 == 110.00 is only true if they are both of the same currency. Its money, so the details are important.

As @tmbb suggests, picking a money lib and convert everything to money first so you know you’re dealing with a currency would be a good recommendation.

kip

kip

ex_cldr Core Team

Money is complicated. Splitting an amount of money is a good case. And indeed there are cases for rounding as well.

  1. The current exchange rate today for USD -> JPY is 111.869. I have USD 24.39 and when converted I end up with JPY 2728.9971

  2. This is a totally valid accounting value (I understand most fintech systems require at least 7 digits of precision but I can’t site a reference for that). But of course eventually we have to put an amount in a customer account that is a settlement value that is a cash amount. Rounding JPY means no decimal digits so the result would be (using the default “half-even” or “bankers rounding” is JPY 2729.

  3. Online services can charge at fractional cents. For example AWS charges $0.192 per Hour for a m5.xlarge instance. Rounding is required prior to billing

  4. Splitting definitely has its own challenges. Splitting a money amount and rounding to the appropriate digits for a currency can leave a balance that shouldn’t be lost. I treat this in ex_money by returning the split amount and the remainder:

iex> Money.split(Money.new!(:USD, "12.43"), 3)
{#Money<:USD, 4.14>, #Money<:USD, 0.01>}

In short, there are valid reasons why a money amount may have more precision that the currency’s definition since intermediate results can create such scenarios. Currency conversion is one good example, interest rate calculations is another, stock trading another one. Eventually to settle accounts rounding will be required and management of the remainder will then also become important.

mudasobwa

mudasobwa

Creator of Cure

One should not try to build malformed partial implementations in any case, but even if all the currencies were having 2 decimals, the money unlike numbers require an ability to split 0.33 into two shares, than join them back and get 0.33. Otherwise the first audit would dismiss the whole business. That is impossible without very careful implementation, that is IMHO harder than anything else in the field.

tmbb

tmbb

You should convert everything to money before adding. The question of 100.00 + 10 shouldn’t even come up

Where Next?

Popular in Questions Top

Fl4m3Ph03n1x
Background Let’s assume I have a typical GenServer that receives messages as requests, does some operation in a DB and returns responses....
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
Kagamiiiii
Student &amp; New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

We're in Beta

About us Mission Statement