How to convert a binary string to an integer or a float?
11,415
Solution 1
No quick way to do it. Use something like this instead:
bin_to_num(Bin) ->
N = binary_to_list(Bin),
case string:to_float(N) of
{error,no_float} -> list_to_integer(N);
{F,_Rest} -> F
end.
This should convert the binary to a list (string), then try to fit it in a float. When that can't be done, we return an integer. Otherwise, we keep the float and return that.
Solution 2
This is the pattern that we use:
binary_to_number(B) ->
list_to_number(binary_to_list(B)).
list_to_number(L) ->
try list_to_float(L)
catch
error:badarg ->
list_to_integer(L)
end.
Solution 3
Intermediate conversion to list is unnecessary since Erlang/OTP R16B:
-spec binary_to_number(binary()) -> float() | integer().
binary_to_number(B) ->
try binary_to_float(B)
catch
error:badarg -> binary_to_integer(B)
end.
Related videos on Youtube
Comments
-
BAR over 3 years
I have binary strings in the form of either:
<<"5.7778345">>
or
<<"444555">>
I do not know before hand whether it will be a float or integer.
I tried doing a check to see if it is an integer. This does not work since it is binary. I alos tried converting binary to list, then check if int or float. I did not have much success with that.
It needs to be a function such as:
binToNumber(Bin) -> %% Find if int or float Return.
Anyone have a good idea of how to do this?
-
I GIVE TERRIBLE ADVICE over 13 yearsNot in this case. Converting with
binary_to_term
andterm_to_binary
will at best change the binary string to a regular list/string. No float or integer will be obtained. See my reply for a way to do it. -
nmichaels over 13 years@I GIVE TERRIBLE ADVICE: I was suggesting using
term_to_binary
to get the binary in the first place. Then converting back is trivial. Of course, it could still be completely unrealistic if the OP doesn't have control over where the data comes from. -
I GIVE TERRIBLE ADVICE over 13 yearsThat makes sense, in that context.
-
YOUR ARGUMENT IS VALID over 13 yearsYou probably want list_to_float not string:to_float.
-
I GIVE TERRIBLE ADVICE over 13 yearsIt would also be a valid approach yes. Probably faster. string:to_float will tolerate more garbage, which might or might not be an advantage. I upvoted your answer.
-
YOUR ARGUMENT IS VALID over 13 yearsI mostly suggested it because <<"123.456seven">> would be considered valid but not <<"123456seven">>. An intentionally garbage tolerant version would be able to handle the integer case too.