Binary to Integer -> Erlang

15,490

Solution 1

[<<"34=",X/binary>>] = M,
list_to_integer(binary_to_list(X)).

That yields the integer 21

Solution 2

As of R16B, the BIF binary_to_integer/1 can be used:

OTP-10300

Added four new bifs, erlang:binary_to_integer/1,2, erlang:integer_to_binary/1, erlang:binary_to_float/1 and erlang:float_to_binary/1,2. These bifs work similarly to how their list counterparts work, except they operate on binaries. In most cases converting from and to binaries is faster than converting from and to lists.

These bifs are auto-imported into erlang source files and can therefore be used without the erlang prefix.

So that would look like:

[<<"34=",X/binary>>] = M,
binary_to_integer(X).

Solution 3

A string representation of a number can be converted by N-48. For multi-digit numbers you can fold over the binary, multiplying by the power of the position of the digit:

-spec to_int(binary()) -> integer().
to_int(Bin) when is_binary(Bin) ->
    to_int(Bin, {size(Bin), 0}).

to_int(_, {0, Acc}) ->
    erlang:trunc(Acc);
to_int(<<N/integer, Tail/binary>>, {Pos, Acc}) when N >= 48, N =< 57 ->
    to_int(Tail, {Pos-1, Acc + ((N-48) * math:pow(10, Pos-1))}).

The performance of this is around 100 times slower than using the list_to_integer(binary_to_list(X)) option.

Share:
15,490
BAR
Author by

BAR

No expertise, just good arguments.

Updated on June 04, 2022

Comments

  • BAR
    BAR almost 2 years

    I have a binary M such that 34= will always be present and the rest may vary between any number of digits but will always be an integer.

    M = [<<"34=21">>]
    

    When I run this command I get an answer like

    hd([X || <<"34=", X/binary >> <- M])
    
    Answer -> <<"21">>
    

    How can I get this to be an integer with the most care taken to make it as efficient as possible?

  • BAR
    BAR over 13 years
    Is this the most efficient way to do it? Any idea why there is not a function to go directly from binary to integer?
  • I GIVE TERRIBLE ADVICE
    I GIVE TERRIBLE ADVICE over 13 years
    because a binary is by default a set of integer. What you have done here is used the representation of integer characters which Erlang knows to interpret as a string. Basically a BIF to do it would 'binary_to_list_to_integer' because <<X, _/binary>> = <<1,2,3>> would already give you just '1' and that's pretty much binary-to-integer conversion, I guess.