Complexity Shock Horror II: the Sequel (was Re: MD5 in erlang

Pierpaolo BERNARDI bernardp@REDACTED
Mon Mar 31 16:34:33 CEST 2003


From: "Tony Rogvall" <tony@REDACTED>

> Here is one suggestion for R9C
>
> integer_to_list(Integer, Base)
>
> where integer(Integer) and Base = bin | oct | hex or dec
>
> - The prefix is not needed sice it is a constant op to cons "16#" or
> whatever as a prefix.

What about negative integers?

BTW, I find this behaviour of the erlang parser puzzling:

51> 16#-123.
-123
52> 16#.
0

Is this intended?  what's its rationale?


> When we are at it, why not do the same thing for list_to_integer?
> I suggest:
> list_to_integer(List, Base)  (base = bin | oct | hex | dec )

When you are at it, why don't you allow underscores in numbers,
like in Ada and Ocaml?

I am using the following:

-export([digit_val/1, digit_val/2, list_to_integer_/1, list_to_integer_/2]).

%%% list_to_integer_("1_23_45") -> 12345
%%% list_to_integer_("_1_23_45") -> error
%%% list_to_integer_("1__23_45") -> error
%%% list_to_integer_("1_23_45_") -> error
%%% list_to_integer_("89AB_CDEF",16) -> 2309737967

list_to_integer_(L) -> list_to_integer_(L,10).

list_to_integer_([$+|T],Base) ->
    list_to_integer_pos(T,Base);
list_to_integer_([$-|T],Base) ->
    -list_to_integer_pos(T,Base);
list_to_integer_(L,Base) ->
    list_to_integer_pos(L,Base).

list_to_integer_pos(L=[C|_],Base) when C =/= $_ ->
    list_to_integer_pos(L,0,Base).

list_to_integer_pos([],Acc,Base) -> Acc;
list_to_integer_pos("_"++(L=[C|_]),Acc,Base) when C =/= $_ ->
    list_to_integer_pos(L,Acc,Base);
list_to_integer_pos([C|L],Acc,Base) ->
    list_to_integer_pos(L,Acc*Base+digit_val(C,Base),Base).

digit_val(C) -> digit_val(C,10).

%%% digit_val($F,16) -> 15
%%% digit_val($f,16) -> 15
%%% digit_val($3) -> 3
%%% digit_val($Z) -> false

digit_val(C,Base) when Base =< 10 ->
    case C >= $0 andalso C < $0 + Base of
        false -> false;
        true -> C - $0
    end;
digit_val(C,Base) when Base > 10 ->
    case digit_val(C,10) of
        false ->
            Base1 = Base - 10,
            case (C >= $A andalso C < $A + Base1) of
                false ->
                    case (C >= $a andalso C < $a + Base1) of
                        false -> false;
                        true -> C - $a + 10
                    end;
                true -> C - $A + 10
            end;
        V -> V
    end.


P.




More information about the erlang-questions mailing list