在 BinData 中实现基本数据类型
Implement a basic datatype in BinData
我正在尝试为半精度浮点类型实现 binary16 encoding。
除一个细节外,代码正常工作:它 return 是一个具有三个属性(符号、指数、分数)的对象,但我希望它 return 浮点数。现在,我必须打电话给 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}
(这实际上不是我自己的回答,我是从 gem 的作者那里收到的。对他的回答做了些微改动,以更好地适应这种问答格式。)
程序描述in the bindata Wiki / Primitive Types
你的情况:
- 子类
Primitive
而不是 Record
- 将
#to_f
重命名为 #get
- 实施
#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
我正在尝试为半精度浮点类型实现 binary16 encoding。
除一个细节外,代码正常工作:它 return 是一个具有三个属性(符号、指数、分数)的对象,但我希望它 return 浮点数。现在,我必须打电话给 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}
(这实际上不是我自己的回答,我是从 gem 的作者那里收到的。对他的回答做了些微改动,以更好地适应这种问答格式。)
程序描述in the bindata Wiki / Primitive Types
你的情况:
- 子类
Primitive
而不是Record
- 将
#to_f
重命名为#get
- 实施
#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