Class: CBOR::Fbox

Inherits:
Box
  • Object
show all
Defined in:
lib/cbor-diag-support.rb

Constant Summary collapse

FLOAT_EI =
{
  "1" => 2,
  "2" => 4,
  "3" => 8
}

Instance Attribute Summary

Attributes inherited from Box

#options, #value

Instance Method Summary collapse

Methods inherited from Box

#cbor_diagnostic, from_number, #inspect, #to_s

Instance Method Details

#make_float(plusbytes, fv) ⇒ Object

Raises:

  • (ArgumentError)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/cbor-diag-support.rb', line 87

def make_float(plusbytes, fv)
  ret =
    if fv.nan?
      # | Format   | Sign bit | Exponent | Significand | Zero
      # | binary16 |        1 |        5 |          10 | 42
      # | binary32 |        1 |        8 |          23 | 29
      # | binary64 |        1 |       11 |          52 | 0
      ds = [fv].pack("G")
      firstword = ds.unpack("n").first
      raise "NaN exponent error #{firstword}" unless firstword & 0x7FF0 == 0x7FF0
      iv = ds.unpack("Q>").first
      ret = case plusbytes
            when 2
              if iv & 0x3ffffffffff == 0 # 42 zero, 10 bits fit in half
                [0xf9, (firstword & 0xFC00) + ((iv >> 42) & 0x3ff)].pack("Cn")
              end
            when 4
              if iv & 0x1fffffff == 0 # 29 zero, 23 bits fit in single
                [0xfa, (ds.getbyte(0) << 24) + ((iv >> 29) & 0xffffff)].pack("CN")
              end
            when 8
              "\xfb".b << ds
            end
    else
      if plusbytes == 8
        [0xfb, fv].pack("CG") # double-precision
      else
        ss = [fv].pack("g")         # single-precision
        if ss.unpack("g").first == fv
          if plusbytes == 4
            "\xfa".b << ss
          else
            if hs = Half.encode_from_single(fv, ss)
              "\xf9".b << hs
            end
          end
        end
      end
    end
  raise ArgumentError, "cbor-diagnostic: make_float #{plusbytes.inspect} #{fv.inspect}" unless ret
  ret
end

#to_cborObject



130
131
132
133
134
135
136
137
138
# File 'lib/cbor-diag-support.rb', line 130

def to_cbor
  if ei = options[:ei]
    plusbytes = FLOAT_EI[ei]
    raise ArgumentError, "cbor-diagnostic: unknown encoding indicator _#{ei} for Float':\n" unless plusbytes
    make_float(plusbytes, value)
  else
    CBOR.encode(value)
  end
end