如何转换几个字节上的大数字?

时间:2012-06-15 22:55:36

标签: erlang

如果一个数字是从4个字节开始,从LSB到MSB,如何将其转换为整数? 例如:

<<77,0,0,0>> shall give 77

<<0,1,0,0>> shall give 256

Let S = <<0,1,0,0>>, 
<<L1,L2,L3,L4>> = S,  
L = L1*1 + L2*256 + L3*65536 + L4*16777216,

但它不优雅......

2 个答案:

答案 0 :(得分:9)

Erlang中的bit syntax以非常简单的方式执行此操作:

<<A:32/little>> = <<0,1,0,0>>,
A.
% A = 256

或作为一种功能:

decode(<<Int:32/little>>) -> Int.

% decode(<<0,1,0,0>>) =:= 256.

答案 1 :(得分:3)

编辑(这是正确的答案,很遗憾发现它很晚......)

> binary:decode_unsigned(<<0,1,0,0>>,little).
256

更简单的方法是:

decode_my_binary( <<A,B,C,D>> ) ->
    A + B*256 + C*65536 + D*16777216.

编辑

根据您的编辑,如果您发现这个不是很优雅,您可以尝试其他方法。我仍然认为以上是正确的做法。你可以写一个递归函数(没有经过测试,但你明白了):

decode( B ) -> decode(binary_to_list(B), 0, 1).
decode( [], R, _ ) -> R;
decode( [H|T], R, F) ->
    decode(T, R + H*F, F*256).

但这显然比较慢。另一种可能性是使用二进制数字列表和乘数列表然后折叠它:

lists:sum(lists:zipwith( fun(X,Y) -> X*Y end,
                   binary_to_list(B), [ math:pow(256,X) || X <- [0,1,2,3] ])).

或者如果你想要一个可变数字的位数:

fun(Digits) ->
    lists:sum(lists:zipwith( fun(X,Y) -> X*Y end,
                   binary_to_list(B), [ math:pow(256,X) || X <- lists:seq(0,Digits-1])).

其中Digits告诉您数字编号。