[m-rev.] for review: format ints with thousand separators
Julien Fischer
juliensf at cs.mu.OZ.AU
Thu Feb 3 17:02:44 AEDT 2005
On Thu, 3 Feb 2005, Ian MacLarty wrote:
> For review by anyone.
>
> Estimated hours taken: 2
> Branches: main
>
> Add predicates and functions to the string module to format integers with
> thousand separators.
>
> library/string.m
> Add predicate and function to convert an int to a string with
s/Add predicate/Add a predicate/
> commas as thousand separators. Add a predicate and function to
> convert an int to any base with any string between any number of
> digits.
>
> tests/general/string_test.exp
> tests/general/string_test.m
> Test the new functionality.
>
> Index: library/string.m
> ===================================================================
> RCS file: /home/mercury1/repository/mercury/library/string.m,v
> retrieving revision 1.226
> diff -u -r1.226 string.m
> --- library/string.m 2 Feb 2005 04:28:49 -0000 1.226
> +++ library/string.m 3 Feb 2005 05:50:13 -0000
> @@ -119,6 +119,13 @@
> :- pred string__int_to_string(int, string).
> :- mode string__int_to_string(in, uo) is det.
>
> + % Convert an integer to a string with commas as thousand seperators.
> + %
> +:- func string__int_to_string_thousands(int) = string.
> +:- mode string__int_to_string_thousands(in) = uo is det.
> +:- pred string__int_to_string_thousands(int, string).
> +:- mode string__int_to_string_thousands(in, uo) is det.
> +
Do we really need the predicate version?
> % string__int_to_base_string(Int, Base, String):
> % Convert an integer to a string in a given Base (between 2 and 36).
> %
> @@ -127,6 +134,17 @@
> :- pred string__int_to_base_string(int, int, string).
> :- mode string__int_to_base_string(in, in, uo) is det.
>
> + % string__int_to_base_string_group(Int, Base, GroupLength, Seperator,
> + % String):
> + % Convert an integer to a string in a given Base (between 2 and 36)
> + % and insert Seperator between every GroupLength digits. Useful
> + % for formatting numbers like "1,300,000".
> + %
This comment should mention that it throws an exception if the Base is not
between 2 and 36.
> +:- func string__int_to_base_string_group(int, int, int, string) = string.
> +:- mode string__int_to_base_string_group(in, in, in, in) = uo is det.
> +:- pred string__int_to_base_string_group(int, int, int, string, string).
> +:- mode string__int_to_base_string_group(in, in, in, in, uo) is det.
> +
Likewise, are we really going to need a predicate verson of this?
> % Convert a float to a string.
> % In the current implementation the resulting float will be in the
> % form that it was printed using the format string "%#.<prec>g".
> @@ -941,6 +959,73 @@
>
> string__from_char_list(CharList, Str) :-
> string__to_char_list(Str, CharList).
> +
> +string__int_to_string_thousands(N) = Str :-
> + string__int_to_base_string_group(N, 10, 3, ",", Str).
> +
> +string__int_to_string_thousands(N, Str) :-
> + string__int_to_base_string_group(N, 10, 3, ",", Str).
> +
> +string__int_to_base_string_group(N, Base, Period, Sep) = Str :-
> + string__int_to_base_string_group(N, Base, Period, Sep, Str).
> +
> +string__int_to_base_string_group(N, Base, Period, Sep, Str) :-
> + (
> + Base >= 2, Base =< 36
> + ->
> + true
> + ;
> + error("string__int_to_base_string_group: invalid base")
> + ),
> + string__int_to_base_string_group_1(N, Base, Period, Sep, Str).
> +
> +:- pred string__int_to_base_string_group_1(int::in, int::in, int::in,
> + string::in, string::uo) is det.
> +
> +string__int_to_base_string_group_1(N, Base, Period, Sep, Str) :-
> + % Note that in order to handle MININT correctly,
> + % we need to do the conversion of the absolute
> + % number into digits using negative numbers
> + % (we can't use positive numbers, since -MININT overflows)
> + (
> + N < 0
> + ->
> + string__int_to_base_string_group_2(N, Base, 0, Period, Sep,
> + Str1),
> + string__append("-", Str1, Str)
> + ;
> + N1 = 0 - N,
> + string__int_to_base_string_group_2(N1, Base, 0, Period, Sep,
> + Str)
> + ).
> +
> +:- pred string__int_to_base_string_group_2(int::in, int::in, int::in, int::in,
> + string::in, string::uo) is det.
> +
> +string__int_to_base_string_group_2(NegN, Base, Curr, Period, Sep, Str) :-
> + (
> + Curr = Period, Period > 0
> + ->
> + string__int_to_base_string_group_2(NegN, Base, 0, Period, Sep,
> + Str1),
> + string__append(Str1, Sep, Str)
> + ;
> + (
> + NegN > -Base
> + ->
> + N = -NegN,
> + char__det_int_to_digit(N, DigitChar),
> + string__char_to_string(DigitChar, Str)
> + ;
> + NegN1 = NegN // Base,
> + N10 = (NegN1 * Base) - NegN,
> + char__det_int_to_digit(N10, DigitChar),
> + string__char_to_string(DigitChar, DigitString),
> + string__int_to_base_string_group_2(NegN1, Base,
> + Curr + 1, Period, Sep, Str1),
> + string__append(Str1, DigitString, Str)
> + )
> + ).
>
That looks ok otherwise.
Julien.
--------------------------------------------------------------------------
mercury-reviews mailing list
post: mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------
More information about the reviews
mailing list