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, 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, 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?, 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



1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
# File 'lib/float-formats/classes.rb', line 1794

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



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

def self.half
  @half
end

.join_halfs(h1, h2) ⇒ Object



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

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

.pack(s, m, e) ⇒ Object



1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
# File 'lib/float-formats/classes.rb', line 1846

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



1823
1824
1825
# File 'lib/float-formats/classes.rb', line 1823

def self.radix
  @half.radix
end

.total_bitsObject



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

def self.total_bits
  8*total_bytes
end

.total_bytesObject



1873
1874
1875
# File 'lib/float-formats/classes.rb', line 1873

def self.total_bytes
  2*@half.total_bytes
end

.total_nibblesObject



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

def self.total_nibbles
  2*total_bytes
end

.unpack(v) ⇒ Object



1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
# File 'lib/float-formats/classes.rb', line 1831

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



1858
1859
1860
1861
1862
1863
1864
# File 'lib/float-formats/classes.rb', line 1858

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