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.

Where Next?

Popular in Questions Top

greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New

Other popular topics Top

WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
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
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36432 110
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54250 245
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement