我必须承认erlang二进制语法让我很困惑。
我想发出文件:change_mod / 2函数,但要准备包含文件模式的整数值(755,740等)我想从一个布尔原子列表中构造它,例如:
[ true, true, true, true, false, true, true, false, true ]
这相当于111 101 101 = 755八进制(base8)
我无法通过位串表示找到直接的方法。
答案 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
期望输入值是一个字节的倍数,因此我们可能需要填充它。