如何将二进制字符串转换为整数或浮点数?

13

我手头有二进制字符串,它们要么是这种形式:

<<"5.7778345">>
或者
<<"444555">>

我事先不知道它是浮点数还是整数。

我尝试进行一次检查以确定它是否为整数。但由于它是二进制的,这不起作用。我还尝试将二进制转换为列表,然后检查是否为int或float。但是我没有取得太大成功。

需要一个函数,例如:

binToNumber(Bin) ->
  %% Find if int or float
  Return.

有人有好的想法来完成这个吗?

4个回答

23

没有快速的方法来完成它。相反,可以使用类似于以下的方式:

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.

这个代码将把二进制转化为一个列表(字符串),然后尝试将其放入浮点数中。当无法完成时,我们返回一个整数。否则,我们保留浮点数并返回它。


你可能想要使用list_to_float而不是string:to_float。 - YOUR ARGUMENT IS VALID
这也是一种有效的方法,可能更快。string:to_float会容忍更多的垃圾,这可能是一个优势,也可能不是。我赞同你的答案。 - I GIVE TERRIBLE ADVICE
1
我主要建议这样做是因为<<"123.456seven">>会被认为是有效的,但<<"123456seven">>不会。一个有意容错的版本也能够处理整数情况。 - YOUR ARGUMENT IS VALID

16

这是我们使用的模式:

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.

1
中间转换为列表在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.

-1

binary_to_term 函数及其对应的 term_to_binary 可能会很有用。


不是这种情况。使用binary_to_termterm_to_binary进行转换,最多只能将二进制字符串转换为常规列表/字符串。无法获得浮点数或整数。请参见我的回复以了解如何处理。 - I GIVE TERRIBLE ADVICE
2
@我给出糟糕的建议:我建议使用term_to_binary来获取二进制数据,然后将其转换回来是微不足道的。当然,如果OP无法控制数据来源,这仍然可能完全不现实。 - nmichaels
在那个情境下,那是有意义的。 - I GIVE TERRIBLE ADVICE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接