[erlang-questions] binary_to_float: <<"2e-1">> versus <<"2.0e-1">>
Per Hedeland
per@REDACTED
Sat Jan 31 14:59:44 CET 2015
Peter Morgan <peter.james.morgan@REDACTED> wrote:
>
>Ah, OK - good to know. I'm using the following as a result:
>
>
>btof(<<Coefficient:8, "e-", Remainder/binary>>) when Coefficient >= $0
>andalso Coefficient =< $9 ->
> binary_to_float(<<Coefficient:8, ".0e-", Remainder/binary>>);
>btof(Float) ->
> binary_to_float(Float).
If you really don't know anything about the format of the numbers you
receive, that seems like a very limited solution. E.g. I suspect that
you want to handle also at least some of
<<"2e1">>,<<"-2e-1">>,<<"+2e-1">>,<<"22e-1">>,<<"2">>,<<".2">>,<<"2.">>
- all of which will result in badarg from binary_to_float/1 with the
above code. Since I happened to have to deal with this "strictness"
recently, I cobbled up the below. I believe it should handle all
"reasonable" (and some not so reasonable) formats that a float can be
"given" in - and (intentionally) crash for anything else. Takes an
iodata() argument, since re(3) does.
--Per Hedeland
to_float(Val) ->
RE = "^\\s*([+-])?(\\d+)?(\\.)?(\\d+)?([Ee][+-]?\\d+)?\\s*$",
{match, [Sign, Int, Point, Fract, Exp]} =
re:run(Val, RE, [{capture, [1, 2, 3, 4, 5], list}]),
list_to_float(Sign ++ float_str(Int, Point, Fract) ++ Exp).
%% make list_to_float/1 happy
float_str(Int, "", "") ->
Int ++ ".0";
float_str("", _, [_|_] = Fract) ->
"0." ++ Fract;
float_str([_|_] = Int, _, "") ->
Int ++ ".0";
float_str([_|_] = Int, _, [_|_] = Fract) ->
Int ++ "." ++ Fract.
More information about the erlang-questions
mailing list