Class: Flt::Num

Inherits:
Object
  • Object
show all
Includes:
Nio::Formattable
Defined in:
lib/nio/rtnlzr.rb,
lib/nio/rtnlzr.rb,
lib/nio/fmt.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Nio::Formattable

append_features, #nio_round, #nio_write

Class Method Details

.nio_read_neutral(neutral) ⇒ Object



1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
# File 'lib/nio/fmt.rb', line 1747

def self.nio_read_neutral(neutral)
  x = nil
  
  if neutral.special?
    case neutral.special
    when :nan
      x = num_class.nan
    when :inf
      x = num_class.infinity(neutral.sign=='-' ? '-1.0' : '+1.0')
    end
  elsif neutral.rep_pos<neutral.digits.length
    
    # uses num_clas.context.precision TODO: ?
    x = num_class.new Rational(*neutral.to_RepDec.getQ)
    
  else
    if neutral.base==num_class.radix
      if neutral.base==10
        str = neutral.sign
        str += neutral.digits
        str += "E#{(neutral.dec_pos-neutral.digits.length)}"
        x = num_class.new(str)
      else
        f = neutral.digits.to_i(neutral.base)
        e = neutral.dec_pos-neutral.digits.length
        s = neutral.sign=='-' ? -1 : +1
        x = num_class.Num(s, f, e)
      end
    else
      # uses num_clas.context.precision TODO: ?
      if num_class.respond_to?(:power)
        x = num_class.Num(neutral.digits.to_i(neutral.base).to_s)
        x *= num_class.Num(neutral.base.to_s)**(neutral.dec_pos-neutral.digits.length)
        x = -x if neutral.sign=='-'
      else
        
        # uses num_clas.context.precision TODO: ?
        x = num_class.new Rational(*neutral.to_RepDec.getQ)
        
      end
    end
  end
  
  return x
end

Instance Method Details

#nio_r(tol = nil) ⇒ Object



132
133
134
135
136
137
138
139
140
# File 'lib/nio/rtnlzr.rb', line 132

def nio_r(tol = nil)
  tol ||= Flt.Tolerance(Rational(1,2),:ulps)
  case tol
    when Integer
      Rational(*Nio::Rtnlzr.max_denominator(self,tol,num_class))
    else
      Rational(*Nio::Rtnlzr.new(tol).rationalize(self))
  end
end

#nio_write_neutral(fmt) ⇒ Object



1792
1793
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
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
# File 'lib/nio/fmt.rb', line 1792

def nio_write_neutral(fmt)
  neutral = Nio::NeutralNum.new
  x = self
  
  if x.nan?
    neutral.set_special(:nan)
  elsif x.infinite?
    neutral.set_special(:inf, x<0 ? '-' : '+')
  else
    converted = false
    if fmt.get_ndig==:exact && fmt.get_approx==:simplify
      
      neutral = x.nio_r(Flt.Tolerance('0.5', :ulps)).nio_write_neutral(fmt)
      # TODO: find better method to accept the conversion
      prc = (fmt.get_base==num_class.radix) ? x.number_of_digits : x.coefficient.to_s(fmt.get_base).length
      prc = [prc, 8].max
      converted = true if neutral.digits.length<prc
      
    elsif fmt.get_approx==:exact && fmt.get_base!=num_class.radix
      # TODO: num_class.context(:precision=>fmt....
      neutral = x.to_r.nio_write_neutral(fmt)
      converted = true
    end
    if !converted
      if fmt.get_base==num_class.radix
        sign = x.sign==-1 ? '-' : '+'
        txt = x.coefficient.to_s(fmt.get_base)  # TODO: can use x.digits directly?
        dec_pos = rep_pos = x.fractional_exponent
        neutral.set sign, txt, dec_pos, nil, fmt.get_base_digits, false ,fmt.get_round
        converted = true
      end
    end
    if !converted
      
      min_exp  =  num_class.context.etiny
      n = x.number_of_digits
      s,f,e = x.split
      b = num_class.radix
      if s < 0
        sign = '-'
      else
        sign = '+'
      end
      prc = x.number_of_digits
      f = num_class.int_mult_radix_power(f, prc-n)
      e -= (prc-n)

      inexact = true

      rounding = case fmt.get_round
      when :even
        :half_even
      when :zero
        :half_down
      when :inf
        :half_up
      when :truncate
        :down
      when :directed_up
        :up
      when :floor
        :floor
      when :ceil
        :ceil
      else
        nil
      end
      

      # TODO: use Num#format instead
      # Note: it is assumed that fmt will be used for for input too, otherwise
      # rounding should be Float.context.rounding (input rounding for Float) rather than fmt.get_round (output)
      formatter = Flt::Support::Formatter.new(num_class.radix, num_class.context.etiny, fmt.get_base)
      formatter.format(x, f, e, rounding, prc, fmt.get_all_digits?)
      inexact = formatter.round_up if formatter.round_up.is_a?(Symbol)
      dec_pos,digits = formatter.digits
      txt = ''
      digits.each{|d| txt << fmt.get_base_digits.digit_char(d)}
      neutral.set sign, txt, dec_pos, nil, fmt.get_base_digits, inexact, fmt.get_round
      
    end
  end
  
  return neutral
end

#nio_xrObject



80
81
82
# File 'lib/nio/rtnlzr.rb', line 80

def nio_xr
  to_r
end