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