在BinData中实现基本数据类型

时间:2017-04-07 11:25:26

标签: ruby bindata

我正在尝试为半精度浮点类型实现binary16 encoding

代码工作除了一个细节:它返回一个具有三个属性(符号,指数,分数)的对象,但我希望它返回浮点数。现在,我必须致电require 'bindata' class Binary16Be < BinData::Record # naming based on https://en.wikipedia.org/wiki/Half-precision_floating-point_format bit1 :sign_bit bit5 :exponent bit10 :fraction def sign sign_bit.zero? ? 1 : -1 end def to_f if exponent == 31 # special value in binary16 - all exponent bits are 1 return fraction.zero? ? (sign * Float::INFINITY) : Float::NAN end sign * 2**(exponent - 15) * (1.0 + fraction.to_f / 1024) end end 才能进入浮动状态。我希望这可以像集成的int和float类一样工作。

这是我的代码:

Binary16Be.read("\x3C\x00")
=> 1.0

我想要的是什么:

Binary16Be.read("\x3C\x00")
{:sign_bit=>0, :exponent=>15, :fraction=>0}

现在发生了什么:

SharedPreferences

1 个答案:

答案 0 :(得分:0)

(这实际上不是我自己的答案,我是从宝石的作者那里得到的。对他的答案略有改动,以便更好地适应这种Q&amp; A格式。) < / p>

该程序描述为in the bindata Wiki / Primitive Types

在你的情况下:

  1. 子类Primitive而不是Record
  2. #to_f重命名为#get
  3. 实施#set
  4. 转换后的代码

    class Binary16Be < BinData::Primitive
      # naming based on
      # https://en.wikipedia.org/wiki/Half-precision_floating-point_format
      bit1 :sign_bit
      bit5 :exponent
      bit10 :fraction
    
      def sign
        sign_bit.zero? ? 1 : -1
      end
    
      def get
        if exponent == 31 # special value in binary16 - all exponent bits are 1
          return fraction.zero? ? (sign * Float::INFINITY) : Float::NAN
        end
        sign * 2**(exponent - 15) * (1.0 + fraction.to_f / 1024)
      end
    
      def set(val)
        self.sign = (val >= 0.0)
        self.fraction = ... # TODO implement
        self.exponent = ... # TODO implement
      end
    end