[erlang-questions] BCD encoding and decodiing

Tony Rogvall <>
Sun Feb 5 00:13:10 CET 2012


Found a better one-liner for encode. Also fixed that N >= 0!
(Still would like to replace the math:pow with something better)

encode(N, S) when N >= 0, S > 0 ->
    << <<(X-$0):4>> || X <- tl(integer_to_list(trunc(math:pow(10,S*2)) + (N rem trunc(math:pow(10,S*2))))) >>.

/Tony

On 4 feb 2012, at 16:21, Tony Rogvall wrote:

> Here is a version not using loops, 'case', 'if', io_lib nor lists (just for fun)
> I put macros here to make the code a bit more readable :-)
> 
> -define(SIGN(X), ((abs((X)+1) - abs((X)-1)) div 2)).
> -define(POSITIVEP(X), ((?SIGN((X)) + 1) div 2)).
> -define(TRUNCD(N,S), ((N) rem trunc(math:pow(10,(S))))).
> 
> encode(N, Size) when N > 0, Size > 0 ->
>     Bits = << <<(X-$0):4>> || X <- integer_to_list(?TRUNCD(N,Size*2))>>,
>     K = Size*8 - bit_size(Bits),
>     <<0:(K*?POSITIVEP(K)),Bits/bits>>.
> 
> 
> decode(Bits) ->
>     list_to_integer([X+$0 || <<X:4>> <= Bits]).
> 
> /Tony
> 
> On 4 feb 2012, at 13:29, Steve Davis wrote:
> 
>> encode(N, Size) ->
>> 	encode0(N, Size * 2, <<>>).
>> 
>> encode0(N, Size, Acc) when Size > 0 ->
>> 	encode0(N div 10, Size - 1, <<(N rem 10):4, Acc/bits>>);
>> encode0(_, _, Acc) ->
>> 	Acc.
>> 
>> decode(N, Size) ->
>> 	case byte_size(N) of
>> 	Size ->
>> 		decode0(N, 0);
>> 	_ ->
>> 		error
>> 	end.
>> 
>> decode0(<<X:4, Bin/bits>>, Acc) ->
>> 	decode0(Bin, Acc * 10 + X);
>> decode0(<<>>, Acc) ->
>> 	Acc.
>> 
>> ..assuming the "size" argument in decode is a constraint. Not sure you
>> need it.
>> 
>> regs,
>> /s
>> 
>> On Feb 3, 11:01 pm, Avinash Dhumane <> wrote:
>>> Can the following encode and decode functions be written without any library calls from modules 'lists' and 'io_lib'? Please show how. The test cases are included at the end. Thanks
>>> 
>>> $ cat bcd.erl
>>> -module(bcd).
>>> -compile(export_all).
>>> % pack the digits of an integer as BCD in a given size of binary
>>> % pad with leading zeros
>>> encode(N, Size) ->
>>>   << <<X:4>> || X <- lists:flatten(io_lib:fwrite("~*..0B", [Size*2, N])) >>.
>>> % unpack the given size of BCD binary into an integer
>>> % strip leading zeros
>>> decode(N, Size) ->
>>>   io_lib:fread("~d", [ X+$0 || <<X:4>> <= <<N:(Size*8)/bits>> ]).
>>> 
>>> $ erl
>>> Eshell V5.8.3  (abort with ^G)
>>> 1> c(bcd).
>>> {ok,bcd}
>>> 2> bcd:encode(1, 5).
>>> <<0,0,0,0,1>>
>>> 3> bcd:decode(v(2), 5).
>>> {ok,[1],[]}
>>> 4> bcd:encode(12345, 5).
>>> <<0,0,1,35,69>>
>>> 5> bcd:decode(v(4), 5).
>>> {ok,[12345],[]}
>>> 6> bcd:encode(1234567890, 5).
>>> <<18,52,86,120,144>>
>>> 7> bcd:decode(v(6), 5).
>>> {ok,[1234567890],[]}
>>> 8>
>>> 
>>> _______________________________________________
>>> erlang-questions mailing list
>>> ://erlang.org/mailman/listinfo/erlang-questions
>> _______________________________________________
>> erlang-questions mailing list
>> 
>> http://erlang.org/mailman/listinfo/erlang-questions
> 
> "Installing applications can lead to corruption over time. Applications gradually write over each other's libraries, partial upgrades occur, user and system errors happen, and minute changes may be unnoticeable and difficult to fix"
> 
> 
> 
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions

"Installing applications can lead to corruption over time. Applications gradually write over each other's libraries, partial upgrades occur, user and system errors happen, and minute changes may be unnoticeable and difficult to fix"



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20120205/a0d95ccf/attachment.html>


More information about the erlang-questions mailing list