【问题标题】:Why is this erlang binary failing binary_to_term/1?为什么这个 erlang 二进制文件失败 binary_to_term/1?
【发布时间】:2016-07-31 23:37:41
【问题描述】:

我将此二进制文件传递给 binary_to_term/1。据我所知,它格式正确,应该可以通过,但它会导致 badarg 错误。谁能告诉我为什么?

> B = <<131,104,3,100,0,2,111,107,100,0,7,82,69,65,76,83,88,80,
      108,0,0,0,1,70,127,240,0,0,0,0,7,162,106>>.

> binary_to_term(B).
** exception error: bad argument
     in function  binary_to_term/1
        called as binary_to_term(<<131,104,3,100,0,2,111,107,100,0,7,82,69,65,76,83,88,
                                   80,108,0,0,0,1,70,127,240,0,0,...>>)

按照文档,二进制文件应该像这样分解:

131  %% encoding version number
104 3  %% a tuple with three elements
100 0 2 111 107  %% the atom length 2 'ok'
100 0 7 82 69 65 76 83 88 80  %% the atom length 7 'REALSXP'
108 0 0 0 1  %% a list with one element
70 127 240 0 0 0 0 7 162  %% a float encoded in eight bytes
106  %% end of list

给予类似的东西:

{ok, 'REALSXP', [123.456]}

唯一看起来不完全清楚的是浮动。是八字节序列

<<127,240,0,0,0,0,7,162>>

对于编码为“8 字节大端 IEEE 格式”的浮点数是否有效?

如果不是 float 部分,这个二进制文件还有什么会导致 binary_to_term 出错?

感谢和祝福

伊万

【问题讨论】:

    标签: erlang


    【解决方案1】:

    这是因为&lt;&lt;127,240,0,0,0,0,7,162&gt;&gt; 是 64 位 IEEE 浮点数中的 NaN 值,而 Erlang 根本不支持创建 NaN 和 Infinity 浮点值(请参阅this)。

    1> <<Sign:1, Exponent:11, Fraction:52>> = <<127,240,0,0,0,0,7,162>>.
    <<127,240,0,0,0,0,7,162>>
    2> Exponent.
    2047
    3> Fraction.
    1954
    4> 16#7ff.
    2047
    

    来自https://en.wikipedia.org/wiki/Double-precision_floating-point_format#Exponent_encoding

    指数00016和7ff16有特殊含义:

    00016 用于表示有符号零(如果 M=0)和次正规(如果 M≠0);和 
    7ff16用于表示∞(如果M=0)和NaNs(如果M≠0),

    其中 M 是小数尾数。

    如果您将这 8 个字节更改为有效的、非 NaN/Infinity 64 位 IEEE 浮点数,则一切正常:

    1> binary_to_term(<<131,104,3,100,0,2,111,107,100,0,7,82,69,65,76,83,88,80,108,0,0,0,1,70,0,0,0,0,0,0,0,0,106>>).
    {ok,'REALSXP',[0.0]}
    

    【讨论】:

    • 绝妙的答案!非常感谢!二进制文件来自 C 端口,NaN 非常适合。我将在 C 端捕获它并更改发送的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 2010-11-29
    • 1970-01-01
    • 2020-09-25
    • 2016-08-27
    • 2018-03-02
    • 1970-01-01
    相关资源
    最近更新 更多