[erlang-questions] How to efficiently set the bit at position Index to 1 in a binary?

Torben Hoffmann <>
Sun Dec 25 20:19:20 CET 2011


However you can write things like this:
set(N, Bin) ->
     a(list_to_binary([<<N:8>>, Bin])).

a(<<N:8, L:N/bits, _:1, R/bits >>)  ->
<< L/bits, 1:1, R/bits >>.

And this works like a charm. It is a very common pattern in 
tele-communication protocols to have a length for a part of the message 
inside the bigger message, so it is not surprising that the binary 
patterns can deal with it.

In fact this "weirdness" is described in $4.6 of the bit_syntax 
documentation - 
http://www.erlang.org/doc/programming_examples/bit_syntax.html

Following that you can write it like:
set2(N, Bin) ->
<<L:N/bits, _:1, R/bits>> = Bin,
<<L/bits, 1:1, R/bits>>.

And this compiles on R14B3 without any warnings (I know, ought to 
update, but haven't had time yet...)

Cheers,
Torben

On 24/12/11 20:17 , Jachym Holecek wrote:
> # Zabrane Mickael 2011-12-24:
>> Hi folks,
>>
>> Here's my code:
>>
>> %%--------------------------------------------------------------------
>> %% @doc Set the bit at position Index to 1 in the binary Bin.
>> %% @end
>> %%--------------------------------------------------------------------
>> -spec set(Bin :: binary(), Index :: non_neg_integer()) ->  binary().
>> set(<<1:1, _/bits>>  = Bin, 0) ->
>>      Bin;
>> set(<<0:1, Rest/bits>>, 0) ->
>>      <<1:1, Rest/bits>>;
>> set(Bin, Index) when Index>  0 ->
>>      Before = Index - 1,
>>      <<Head:Before, _:1, Rest/bits>>  = Bin,
>>      <<Head:Before, 1:1, Rest/bits>>.
>>
>>
>> After compiling, I'm getting the following warnings:
>> src/foo.erl:248: Warning: INFO: the '=' operator will prevent delayed sub binary optimization
>> src/foo.erl:248: Warning: INFO: the '=' operator will prevent delayed sub binary optimization
>> src/foo.erl:250: Warning: NOT OPTIMIZED: sub binary is used or returned
>> src/foo.erl:254: Warning: NOT OPTIMIZED: sub binary is used or returned
>>
>> What's the best/optimized solution and how to get rid of these warnings?
> Binary matching is *much* more powerful than what it looks like at first:
>
>    -module(a).
>    -export([a/2]).
>
>    a(N, B) ->
>        fun (<<L:N/bits, _:1, R/bits>>) ->
>            <<L/bits, 1:1, R/bits>>
>        end(B).
>
> The compiler refuses the saner form (doing the binary match in a/1's head
> directly) quoting the delusion that N isn't bound at that point... pity.
>
> Have fun,
> 	-- Jachym
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list