如何在erlang中从一系列布尔原子中创建八进制表示

时间:2013-06-04 21:09:21

标签: erlang

我必须承认erlang二进制语法让我很困惑。

我想发出文件:change_mod / 2函数,但要准备包含文件模式的整数值(755,740等)我想从一个布尔原子列表中构造它,例如:

[ true, true, true, true, false, true, true, false, true ] 

这相当于111 101 101 = 755八进制(base8)

我无法通过位串表示找到直接的方法。

3 个答案:

答案 0 :(得分:3)

另一种方式:

-module(bits).

-export([bit_flag/1]).

bit_flag(Flags) ->
    Bits = length(Flags),
    <<X:Bits/integer>> = << <<(to_bit(Flag)):1/integer>> || Flag <- Flags >>,
    X.

to_bit(true) -> 1;
to_bit(false) -> 0.

答案 1 :(得分:2)

一种方式可能是这样的:

List = [ true, true, true, true, false, true, true, false, true ],

{_, Mode} = lists:foldr(
    fun(A, {M, S}) -> {M * 2, (A * M) + S } end,
    {1, 0},
    [case X of true -> 1; false -> 0 end || X <- List]
).

Mode =:= 8#755.
true

io:format("~.8B~n", [Mode]).
755
ok

或作为模块:

-module(change_mode_utils).

-export([bool_list_to_mode/1]).

-spec bool_list_to_mode(List::[boolean()]) -> integer().
bool_list_to_mode(List) when is_list(List) ->
    {_, Mode} = lists:foldr(
        fun(true,  {M, S}) -> { M * 2, M + S };
           (false, {M, S}) -> { M * 2,     S } end,
        {1, 0},
        List
    ),
    Mode.

证明

1> c(change_mode_utils).
{ok,change_mode_utils}
2> change_mode_utils:bool_list_to_mode(
    [ true, true, true, true, false, true, true, false, true ]
) =:= 8#755.
true

答案 2 :(得分:1)

这是我到目前为止所提出的:

1> Inp = [true, true, true, true, false, true, true, false, true].
[true,true,true,true,false,true,true,false,true]
2> Lst = [if X =:= true -> 1; X =:= false -> 0 end || X <- Inp].
[1,1,1,1,0,1,1,0,1]
3> B = lists:foldl(fun(A, AccIn) -> <<AccIn/bits,A:1>> end, <<>>, Lst).
<<246,1:1>>
4> Int = binary:decode_unsigned(<<0:((8-(bit_size(B) rem 8)) rem 8), B/bits>>).
493
5> io:fwrite("~.8B~n", [Int]).
755
ok
6>

function binary:decode_unsigned期望输入值是一个字节的倍数,因此我们可能需要填充它。