Convert decimal to string with fixed decimal places

2,574 views
Skip to first unread message

Max F.

unread,
Sep 29, 2015, 5:53:53 AM9/29/15
to elixir-lang-talk
Hi all,

In an app I'm writing, I'm using the decimal library to handle money values. When I print these values as string, I'd like to format them so that they always show exactly two decimal digits; eg:
  • Decimal.new("1") is formatted as "1.00"
  • Decimal.new("1.5") is formatted as "1.50"
  • Decimal.new("1.123") is formatted as "1.12"
Is there a way of doing this? I've searched the documentation and experimented with a few different approaches, but I can't find it.

Many thanks,

Max


eksperimental

unread,
Sep 29, 2015, 6:01:03 AM9/29/15
to elixir-l...@googlegroups.com
yes, you can do it.

iex(22)> Float.to_string(1.234, decimals: 2)
"1.23"
iex(23)> Float.to_string(1.234, decimals: 10)
"1.2340000000"


On Tue, 29 Sep 2015 02:53:53 -0700 (PDT)
"Max F." <massimili...@gmail.com> wrote:

> Hi all,
>
> In an app I'm writing, I'm using the decimal library to handle money
> values. When I print these values as string, I'd like to format them
> so that they always show exactly two decimal digits; eg:
>
> - Decimal.new("1") is formatted as "1.00"
> - Decimal.new("1.5") is formatted as "1.50"
> - Decimal.new("1.123") is formatted as "1.12"

José Valim

unread,
Sep 29, 2015, 6:24:56 AM9/29/15
to elixir-l...@googlegroups.com
You shouldn't rely on float because of imprecision though. Using the Decimal library, can't you use Decimal.to_string/2 to achieve what you want?



José Valim
Skype: jv.ptec
Founder and Director of R&D

--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/20150929170054.5e8d5c12.eksperimental%40autistici.org.
For more options, visit https://groups.google.com/d/optout.

Ed W

unread,
Sep 29, 2015, 6:32:09 AM9/29/15
to elixir-l...@googlegroups.com
No, I don't think this is right? You are using Floats and as per my
previous rant on this, there are a lot of issues with the default
rounding on floats

I haven't used the decimal library in anger, but I would expect you to
need to use the Decimal.to_string function and checking the code implies
you would first need to update the rounding to the correct decimal
places you want for display.

Actually, this seems a bit ugly, I wonder if Eric might not accept a
formatting patch to improve this? It would need additional options to
accept decimal places (and/or sig figures) and then (after some
arithmetic) trim the digit list to the correct length. Edit: I see you
might also need to pad the list with zeros

I was previously quite pleased with my "stringify" function here. It
effectively takes a string of digits, such as the internal list that
Eric's library is maintaining, and prints them out in various formats
with the decimal in the right place:
https://github.com/ewildgoose/elixir-float_pp/blob/master/lib/float_pp.ex

Please don't use that whole project directly, it was an attempt add
adding correct pretty printing of arbitrary floats. Eric's library
includes the important meat of this, plus various rounding and
arithmetic options. However, my formatting code looks more capable,
perhaps you could rip that out and send him a patch..?

Ed W

Eric Meadows-Jönsson

unread,
Sep 29, 2015, 7:14:41 AM9/29/15
to elixir-l...@googlegroups.com
The current decimal printing follows the specifications linked from the library's documentation so it can't be changed, but if you find ways to improve the code please send a PR. I would also accept patches that adds functionality such as printing N number of digits or decimal places.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Eric Meadows-Jönsson

Ed W

unread,
Sep 29, 2015, 7:56:38 AM9/29/15
to elixir-l...@googlegroups.com
On 29/09/2015 12:14, Eric Meadows-Jönsson wrote:
> The current decimal printing follows the specifications linked from
> the library's documentation so it can't be changed, but if you find
> ways to improve the code please send a PR. I would also accept patches
> that adds functionality such as printing N number of digits or decimal
> places.
>

Agreed.

I have what I think is a nice implementation of output of the stream of
digits in my abandoned file here:
https://github.com/ewildgoose/elixir-float_pp/blob/master/lib/float_pp.ex

I guess my naming of inputs is different, but it takes a string of
digits plus location of the decimal and prints it in various formats
(including arbitrary padding). I don't have capacity to prepare a nice
patch at present, but literally the code from stringify downwards should
be taken. I feel it's fairly well documentated and neat... Perhaps
someone else could pull it out and prepare a patch... (hint)

Thanks for "decimal"! I'm not using it, but I'm a big fan!

Cheers

Ed W

Max F.

unread,
Sep 29, 2015, 8:43:28 AM9/29/15
to elixir-lang-talk
Thank you all for your replies so far, and in particular to Eric for pointing out that the current implementation actually follows the specification.

Given this, a possible solution would be to set the exponent of the decimal before printing. I see in the specification there is a quantize function that does exactly that. Maybe this would be useful addition to the library? If so I'd be happy to try and pull something together.

Max
Reply all
Reply to author
Forward
0 new messages