Erlang Central

Commas in Numbers

Revision as of 01:32, 26 August 2006 by Cyberlync (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)


You need to format a number for printing with commas (or other locale-dependant marks) in the appropriate places. This is important for creating human-legible print copies of reports.


Use the Perl-compatible regular expression engine to insert the commas where needed. It's simplest to reverse the string prior to the regexp-pass so that we can hop over any decimal portion. Then reverse the string back on return.

partition_number(Number, Separator) ->
    SepChar = hd(Separator),
    NumStr = if
       is_integer(Number) -> hd(io_lib:format("~B", [Number]));
       is_float(Number) -> hd(io_lib:format("~f", [Number]));
       true -> Number
    % If there is a decimal point, use that as the starting point
    {ChgStr, Remain} = case regexp:first_match(NumStr, "\\.") of
        {match,Start,Length} ->
       {string:substr(NumStr, 1, Start - 1),
   nomatch -> {NumStr, ""}
    {ok, Subs, _} = regexp:gsub(lists:reverse(ChgStr),
       "([0-9][0-9][0-9])", "&" ++ Separator),
    Final = case lists:nth(string:len(Subs), Subs) of
        SepChar -> string:substr(Subs, 1, string:len(Subs) - 1);
        _       -> Subs
    lists:reverse(Final) ++ Remain.

While this function works, it would be better if it checked for someone passing the separator parameter as a character (rather than a string).

Here's an example of partition_number in action:

1> partition_number(1918928282, ",").
2> partition_number(1982928828, "'"). 
3> partition_number(1982928828.12345, "'").

In addition to Erlang's various other string-related ills (mainly poor memory and time performance), it has a very limited set of regular expressions. For example, our implementation of partition_number is over twice as long as the [[1][Scheme alternative] because it has no look-ahead (or negative look-ahead) searching functionality.