2017-04-07 158 views
0

我正在嘗試爲半精度浮點類型實現binary16 encoding在BinData中實現一個基本的數據類型

代碼工作除了一個細節:它返回一個具有三個屬性(符號,指數,分數)的對象,但我希望它返回浮點數。現在,我不得不打電話to_f去浮動。我希望能夠像集成的int和float類一樣工作。

這裏是我的代碼:

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 

我想什麼:

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

現在會發生什麼:

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

回答

0

(這其實不是我自己的答案,我從寶石的作者那裏得到了這個。對他的答案做了些微的改動以適應這個Q &格式更好一點)

程序中描述in the bindata Wiki/Primitive Types

你的情況:

  1. 子類的Primitive代替Record
  2. 重命名#to_f#get
  3. 實現#set

轉換後的代碼

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 
相關問題