2016-09-21 10 views
3

Erlangを使用してバイナリファイルで4バイト(リトルエンディアン)を読みました。バイナリファイルから単精度浮動小数点数を読み取ってErlang floatに変換する方法は?

浮かぶようにバイナリに変換しようとしますが、私は下に遭遇したエラーを保った:それはフロートパターンに一致しているように見えるし、代わりにlist_to_integerを呼び出すまで終わらない

** exception error: bad argument 
    in function list_to_integer/1 
     called as list_to_integer([188,159,21,66]) 

。単精度浮動小数点を自然Erlang浮動小数点に変換するにはどうすればよいですか?以下

私のErlangの機能:

readfloat(S, StartPos) -> 
    io:format("Pos: ~w~n", [StartPos - 1]), 
    case file:pread(S, StartPos - 1, 4) of 
    eof -> 
     ok; 
    {ok, Data} -> 
     % io:format("Wut: ~w~n", Data), 
     N = binary_to_list(Data), 
     case string:to_float(N) of 
      {error,no_float} -> 
       list_to_integer(N); 
      {F,_Rest} -> 
       F 
     end 

     % have tried this section as well, error too 
     % N = binary_to_list(Data), 
     % try list_to_float(N) 
     % catch 
      % error:badarg -> 
       % list_to_integer(N) 
     % end 
    end. 

答えて

6

string:to_floatは、引数が数の表示表現であることを期待しますが、この場合には、あなたはバイナリ表現を持っています。 bit syntax expressionを使用して変換できます。ある

> Y = <<188,159,21,66>>. 
<<188,159,21,66>> 
> <<Z:32/float-little>> = Y. 
<<188,159,21,66>> 
> Z. 
37.40599060058594 

は、バイナリに対してパターン一致を実行し、リトルエンディアン、32ビット浮動小数点数を抽出し、可変Zに割り当てます。

NB:エンディアンを指定しない場合、アーランはデフォルトでビッグエンディアンになります。 big,littleまたはnativeのいずれかとして明示的に指定できます。

7

あなたは単に読み取る4バイト(IEEE 754に従って)単精度浮動小数点のバイナリ表現であることがわかっている場合は、ヨーヨーはWikipedia pageで与えられた定義を使用して、フロートに変換することができる:

1> Float = fun(B) -> <<S:1,E:8,M:23>> = B, 
1>  case {S,E,M} of 
1>   {_,0,0} -> 0; % you may make distinction between +0 and -0 
1>   {1,255,0} -> minus_infinity; 
1>   {0,255,0} -> infinity; 
1>   {_,255,_} -> nan; 
1>   {S,0,M} -> (1-2*S)*M/(1 bsl 149); % denormalized number 
1>   {S,E,M} when E > 150 -> float((1-2*S)*(M+ (1 bsl 23)) * (1 bsl (E - 150))); 
1>   {S,E,M} -> (1-2*S)*(M+ (1 bsl 23))/(1 bsl (150-E)) 
1>  end 
1> end. 1>end. #Fun<erl_eval.6.52032458> 
2> Float(<<192,0,0,0>>). 
-2.0 
3> Float(<<188,159,21,66>>).             
-0.019419316202402115 
4> Float(<<194,237,64,0>>). 
-118.625 

[編集]いつものよう私は手遅れだ:O)、そして私は、バイナリ試合のために、この構文を覚えていませんでした:<<Z:32/float>>:!(

+1

完璧なソリューションoをまれどこで詳細なバイナリ数学を見ることができますありがとうございました。君は。 –

関連する問題