首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何检查在Elixir/ Erlang中是否设置了特定位

如何检查在Elixir/ Erlang中是否设置了特定位
EN

Stack Overflow用户
提问于 2017-08-17 09:36:44
回答 2查看 941关注 0票数 1

给定任何二进制(例如<<1, 0, 110, 64>> ),我们如何确定是否设置了特定位?

假设我们希望确定bit-1和bit-2是否已设置,人们可能会认为这是可行的,但它没有:

代码语言:javascript
复制
<<bit1::bits-size(1), bit2::bits-size(1), _rest::bits>> = <<1, 0, 110, 64>>

给予:

代码语言:javascript
复制
iex(5)> {bit1, bit2}                                                                
{<<0::size(1)>>, <<0::size(1)>>}

正确答案(来自Igor和其他评论):

<<_::bits-6, bit2::bits-1, bit1::bits-1, num::bits>> = <<1, 0, 110, 64>>

给出了预期的答案:

{bit1,bit2} = {1, 0}

背景

我正在构建一个解析器来处理这个问题:https://msdn.microsoft.com/en-us/library/vs/alm/dd943386(v=office.12).aspx

使用这个C#代码作为模板,我得到了正确的结果:<<1, 0, 110, 64>> = 2.4

SourceCode/NPOI/HSSF/Util/RKUtil.cs#L33-L74

我的上述功能的等效Elixir实现如出一辙,但我相信使用位字符串解析应该是可能的(并且更干净)。

代码语言:javascript
复制
def rk_number(data) do
    # IO.puts " ** rk-data: #{inspect data}"

    n0 = :binary.decode_unsigned(data, :little)
    n1 = n0 >>> 2

    n2 =
      if (n0 &&& 0x2) == 0x2 do # bit-2, is an int
        <<v::little-signed-32>> = <<n1::little-32>>
        v
      else
        n3 = n1 <<< 34
        <<v::little-float-64>> = <<n3::little-64>>
        v
      end

    if (n0 &&& 0x1) == 0x1 do # bit-1, div by 100
      n2 / 100
    else
      n2
    end
  end
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-17 09:58:02

这是因为默认情况下,<<1, 0, 110, 64>>表示中的每个数字都具有大小8

怪不得

代码语言:javascript
复制
<<bit1::bits-size(1), bit2::bits-size(1), _rest::bits>> = <<1, 0, 110, 64>>
{bit1, bit2} = {<<0::size(1)>>, <<0::size(1)>>}

因为1 of size 8 (00000001)中的第2位等于0

代码语言:javascript
复制
<<bit1::bits-size(8), bit2::bits-size(8), _rest::bits>> = <<1, 0, 110, 64>>
{bit1, bit2} = {<<1>>, <<0>>}

代码语言:javascript
复制
<<bit1::bits-size(1), bit2::bits-size(1), _rest::bits>> = <<1::size(1), 0::size(1), 110, 64>>
{bit1, bit2} = {<<1::size(1)>>, <<0::size(1)>>}      

如果有一个整数,并且试图得到它的前两位,您可以尝试这样的方法:

代码语言:javascript
复制
<<bit1::bits-size(1), bit2::bits-size(1), _rest::bits>> = :binary.encode_unsigned(your_integer)
票数 3
EN

Stack Overflow用户

发布于 2017-08-17 10:23:43

我得到了答案,在考虑了上面的一条评论之后:

<<_::bits-6, bit2::bits-1, bit1::bits-1, num::bits>> = <<1, 0, 110, 64>>

{bit1, bit2} = {1, 0}

给出了预期的结果

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45731529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档