module Gogyou::Aux
Public Class Methods
define_pack_binary(mod, name, bitsize, exponent_bitsize, fraction_bitsize)
click to toggle source
# File lib/gogyou/extensions.rb, line 8 def self.define_pack_binary(mod, name, bitsize, exponent_bitsize, fraction_bitsize) sign_bit = 1 << (fraction_bitsize + exponent_bitsize) fraction_bitmask = ~(~0 << fraction_bitsize) exponent_bitmask = ~(~0 << exponent_bitsize) exponent_bias = (exponent_bitmask >> 1) - 1 exponent_max = (exponent_bitmask >> 1) + 2 exponent_min = -exponent_max fraction_msb = 1 << fraction_bitsize fraction_bias = 1 << (fraction_bitsize + 1) nan = (exponent_bitmask << fraction_bitsize) | (fraction_msb >> 1) infinity = (exponent_max + exponent_bias) << fraction_bitsize mod.module_eval(<<-EOS, __FILE__, __LINE__ + 1) def #{name} num = Float(self) return #{nan} if num.nan? n = (num < 0 || (1 / num) < 0) ? #{sign_bit} : 0 return n if num == 0 return n | #{infinity} if num.infinite? num = -num unless n == 0 (coefficient, e) = Math.frexp(num) case when e > #{exponent_max} n | #{infinity} when e < #{exponent_min} n else coefficient = (coefficient * #{fraction_bias}).to_i n |= ((e + #{exponent_bias}) & #{exponent_bitmask}) << #{fraction_bitsize} n | coefficient & #{fraction_bitmask} end end EOS end
define_unpack_binary(mod, name, bitsize, exponent_bitsize, fraction_bitsize)
click to toggle source
# File lib/gogyou/extensions.rb, line 47 def self.define_unpack_binary(mod, name, bitsize, exponent_bitsize, fraction_bitsize) sign_bit = 1 << (fraction_bitsize + exponent_bitsize) fraction_bitmask = ~(~0 << fraction_bitsize) exponent_bitmask = ~(~0 << exponent_bitsize) exponent_bias = (exponent_bitmask >> 1) - 1 fraction_msb = 1 << fraction_bitsize fraction_bias = (1 << (fraction_bitsize + 1)).to_f mod.module_eval(<<-EOS, __FILE__, __LINE__ + 1) def #{name} n = self.to_i e = (n >> #{fraction_bitsize}) & #{exponent_bitmask} s = (n & #{sign_bit}) != 0 case e when 0 return s ? -0.0 : 0.0 when #{exponent_bitmask} if (n & #{fraction_bitmask}) != 0 return Float::NAN else return s ? -Float::INFINITY : Float::INFINITY end end e -= #{exponent_bias} c = ((n & #{fraction_bitmask}) | #{fraction_msb}) / #{fraction_bias} num = Math.ldexp(c, e) num = -num if s num end EOS end