Class: Flt::DoubleFormat

Inherits:
FormatBase show all
Defined in:
lib/float-formats/classes.rb

Overview

Class to define formats such as “double double” by pairing two floating-point values which define a higher precision value by its sum. The :half parameter is a format class that defines the type of each part of the numbers. The formats defined here have a fixed precision, although these formats can actually have a variable precision. For binary formats there’s an option to gain one bit of precision by adjusting the sign of the second number. This is enabled by the :extra_prec option. For example, the “double double” format used in PowerPC is this

Flt.define :DoubleDouble, DoubleFormat, half: IEEE_binary64, extra_prec: true

Although this has a fixed 107 bits precision, the format as used in the PowerPC can have greater precision for specific values (by having greater separation between the exponents of both halves)

Constant Summary

Constants included from Flt

APPLE, HFP_DOUBLE, HFP_EXTENDED, HFP_SINGLE, IEEE_128, IEEE_128_BE, IEEE_DEC128, IEEE_DEC32, IEEE_DEC64, IEEE_DOUBLE, IEEE_D_BE, IEEE_EXTENDED, IEEE_HALF, IEEE_H_BE, IEEE_QUAD, IEEE_Q_BE, IEEE_SINGLE, IEEE_S_BE, IEEE_X_BE, IEEE_binaryx, MBF_EXTENDEND, RPL, RPL_X

Instance Attribute Summary

Attributes inherited from FormatBase

#exponent, #sign, #significand

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from FormatBase

#<=>, arithmetic, arithmetic_type, bias, canonicalized, context, #convert_to, decimal_digits_necessary, decimal_digits_stored, decimal_max_exp, decimal_min_exp, endianness, epsilon, #form_class, #fp_format, from, from_bits, from_bits_text, from_bytes, from_hex, from_number, from_text, gradual_underflow?, half_epsilon, #infinite?, infinity, #initialize, join, max_value, maximum_integral_significand, min_normalized_value, min_value, minimum_normalized_integral_significand, #minus, minus_sign_value, nan, #nan?, #next_minus, #next_plus, #normal?, normalized?, num, num_class, numerals_conversion, pack_fields_hash, radix_log, radix_log10, radix_max_exp, radix_min_exp, radix_power, rounding_mode, sign_from_unit, sign_to_unit, #split, strict_epsilon, #subnormal?, switch_sign_value, #to, #to_a, #to_bits, #to_bits_text, #to_bytes, #to_hex, #to_num, #to_text, #ulp, unpack_fields_hash, zero, #zero?

Methods included from Flt

#*, #+, #-, #-@, #/, bcd2dpd, bitnot, convert_bytes, dbl_from_float, dbl_from_text, dbl_to_float, dpd2bcd, dpd_to_hexbcd, float_bin, float_dec, float_from_integral_sign_significand_exponent, float_from_integral_significand_exponent, float_shortest_dec, float_significant_dec, float_to_integral_sign_significand_exponent, float_to_integral_significand_exponent, hex_from_float, hex_to_float, hexbcd_to_dpd, sgl_from_float, sgl_from_text, sgl_to_float

Constructor Details

This class inherits a constructor from Flt::FormatBase

Class Method Details

.define(params) ⇒ Object



1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
# File 'lib/float-formats/classes.rb', line 1799

def self.define(params)
  @half = params[:half]
  params = @half.parameters.merge(params)
  if @half.radix==2
    @extra_prec = params[:extra_prec]
  else
    @extra_prec = false
  end
  params[:significand_digits] = 2*@half.significand_digits
  params[:significand_digits] += 1 if @extra_prec
  @significand_digits = params[:significand_digits]

  @hidden_bit = params[:hidden_bit] = @half.hidden_bit

  fields1 = []
  fields2 = []
  params[:fields].each_slice(2) do |s,v|
    fields1 << s # (s.to_s+"_1").to_sym
    fields1 << v
    fields2 << (s.to_s+"_2").to_sym
    fields2 << v
  end
  params[:fields] = fields1 + fields2

  define_fields params[:fields]

  super params
end

.halfObject



1832
1833
1834
# File 'lib/float-formats/classes.rb', line 1832

def self.half
  @half
end

.join_halfs(h1, h2) ⇒ Object



1871
1872
1873
# File 'lib/float-formats/classes.rb', line 1871

def self.join_halfs(h1,h2)
  self.from_bytes(h1.to_bytes+h2.to_bytes)
end

.pack(s, m, e) ⇒ Object



1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
# File 'lib/float-formats/classes.rb', line 1851

def self.pack(s,m,e)
  if e.kind_of?(Symbol)
    f1 = @half.pack(s,m,e)
    f2 = @half.pack(+1,0,:zero)
  else
    s1,m1,e1,s2,m2,e2 = split_fp(s,m,e)
    f1 = @half.pack(s1,m1,e1)
    f2 = @half.pack(s2,m2,e2)
  end
  f1+f2
end

.radixObject



1828
1829
1830
# File 'lib/float-formats/classes.rb', line 1828

def self.radix
  @half.radix
end

.total_bitsObject



1881
1882
1883
# File 'lib/float-formats/classes.rb', line 1881

def self.total_bits
  8*total_bytes
end

.total_bytesObject



1878
1879
1880
# File 'lib/float-formats/classes.rb', line 1878

def self.total_bytes
  2*@half.total_bytes
end

.total_nibblesObject



1875
1876
1877
# File 'lib/float-formats/classes.rb', line 1875

def self.total_nibbles
  2*total_bytes
end

.unpack(v) ⇒ Object



1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
# File 'lib/float-formats/classes.rb', line 1836

def self.unpack(v)
  sz = @half.total_bytes
  v1 = @half.unpack(v[0...sz])
  v2 = @half.unpack(v[sz..-1])
  if v1.last == :nan
    nan
  elsif v1.last == :infinity
    infinity(v1.sign)
  else
    v2 = @half.zero.split if @half.new(*v1).subnormal?
    params = v1 + v2
    join_fp(*params)
  end
end

Instance Method Details

#split_halfsObject



1863
1864
1865
1866
1867
1868
1869
# File 'lib/float-formats/classes.rb', line 1863

def split_halfs
  b = to_bytes
  sz = form_class.half.total_bytes
  b1 = b[0...sz]
  b2 = b[sz..-1]
  [form_class.half.from_bytes(b1), form_class.half.from_bytes(b2)]
end