[erlang-questions] BCD encoding and decodiing

Hynek Vychodil <>
Mon Feb 6 11:52:26 CET 2012


Another possible solution:

-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) ->
  encode(N, Size, []).

encode(_, 0, Acc) -> list_to_binary(Acc);
encode(N, Size, Acc) ->
  B  = N  rem 10,
  N1 = N  div 10,
  A  = N1 rem 10,
  N2 = N1 div 10,
  encode(N2, Size - 1, [(A bsl 4) + B | Acc]).

% unpack the given size of BCD binary into an integer
% strip leading zeros
decode(N, Size) when size(N) =:= Size ->
  decode(N).

decode(<<>>) -> "0";
decode(<<0,Rest/binary>>) -> decode(Rest);
decode(<<0:4,X:4,Rest/binary>>) ->
  [$0 + X | decode_(Rest)];
decode(N) -> decode_(N).

decode_(N) ->
  [ $0+X ||  <<X:4>> <= N ].

On Sun, Feb 5, 2012 at 12:13 AM, Tony Rogvall <> wrote:
> 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"
>
>
>
>
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions
>



-- 
Hynek Vychodil
BI consultant

GoodData
náměstí 28. října 1104/17, 602 00, Brno - Černá Pole
Office:   +420 530 50 7704
E-mail:  
Web:     www.gooddata.com



More information about the erlang-questions mailing list