Class: LargeBinomials::LargeFloat

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/large_binomials/large_float.rb

Overview

Class modeling floats larger than Ruby’s regular float. They consist of a regular float (the mantissa) plus an additional exponent of 10.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(m, e = 0) ⇒ LargeFloat

Returns a new instance of LargeFloat.



29
30
31
32
# File 'lib/large_binomials/large_float.rb', line 29

def initialize(m, e = 0)
  @mantissa = m.to_f
  @exponent = e
end

Instance Attribute Details

#exponentObject

Returns the value of attribute exponent.



27
28
29
# File 'lib/large_binomials/large_float.rb', line 27

def exponent
  @exponent
end

#mantissaObject

Returns the value of attribute mantissa.



27
28
29
# File 'lib/large_binomials/large_float.rb', line 27

def mantissa
  @mantissa
end

Instance Method Details

#*(other) ⇒ Object



46
47
48
49
50
51
52
# File 'lib/large_binomials/large_float.rb', line 46

def *(other)
  if other.instance_of? LargeFloat
    multiply_with_large_float(other)
  else
    multiply_with_numeric(other)
  end
end

#+(other) ⇒ Object



97
98
99
100
101
102
103
# File 'lib/large_binomials/large_float.rb', line 97

def +(other)
  if self < other
    other + self
  else
    LargeFloat.new(new_mantissa_for_addition(other), @exponent)
  end
end

#/(other) ⇒ Object



73
74
75
76
77
78
79
# File 'lib/large_binomials/large_float.rb', line 73

def /(other)
  if other.instance_of? LargeFloat
    divide_by_large_float(other)
  else
    divide_by_numeric(other)
  end
end

#<=>(other) ⇒ Object



117
118
119
120
121
122
123
124
125
# File 'lib/large_binomials/large_float.rb', line 117

def <=>(other)
  normalize
  other.normalize
  if @exponent == other.exponent
    @mantissa - other.mantissa
  else
    @exponent - other.exponent
  end
end

#cloneObject



34
35
36
# File 'lib/large_binomials/large_float.rb', line 34

def clone
  LargeFloat.new(@mantissa, @exponent)
end

#divide_by_large_float(lf) ⇒ Object



81
82
83
84
85
# File 'lib/large_binomials/large_float.rb', line 81

def divide_by_large_float(lf)
  quotient = self / lf.mantissa
  quotient.exponent -= lf.exponent
  quotient
end

#divide_by_numeric(n) ⇒ Object



87
88
89
90
91
# File 'lib/large_binomials/large_float.rb', line 87

def divide_by_numeric(n)
  quotient = clone
  quotient.mantissa /= n
  quotient
end

#multiply_with_large_float(lf) ⇒ Object



54
55
56
57
58
# File 'lib/large_binomials/large_float.rb', line 54

def multiply_with_large_float(lf)
  product = self * lf.mantissa
  product.exponent += lf.exponent
  product
end

#multiply_with_numeric(i) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/large_binomials/large_float.rb', line 60

def multiply_with_numeric(i)
  product = clone
  new_mantissa = product.mantissa * i
  product.normalize if new_mantissa == Float::INFINITY
  new_mantissa = product.mantissa * i
  if new_mantissa == Float::INFINITY
    product.exponent += 1
    i /= 10
  end
  product.mantissa *= i
  product
end

#new_mantissa_for_addition(lf) ⇒ Object



93
94
95
# File 'lib/large_binomials/large_float.rb', line 93

def new_mantissa_for_addition(lf)
  @mantissa + lf.mantissa * 10**(lf.exponent - @exponent)
end

#normalizeObject



38
39
40
41
42
43
44
# File 'lib/large_binomials/large_float.rb', line 38

def normalize
  unless @mantissa == 0
    normalization = Math.log10(@mantissa.abs).floor
    @mantissa /= 10**normalization
    @exponent += normalization
  end
end

#superscript(i) ⇒ Object



105
106
107
108
109
110
# File 'lib/large_binomials/large_float.rb', line 105

def superscript(i)
  s = i.to_s
  s = s.gsub(/1/, '¹').gsub(/2/, '²').gsub(/3/, '³').gsub(/4/, '')
  s = s.gsub(/5/, '').gsub(/6/, '').gsub(/7/, '').gsub(/8/, '')
  s.gsub(/9/, '').gsub(/0/, '').gsub(/-/, '')
end

#to_sObject



112
113
114
115
# File 'lib/large_binomials/large_float.rb', line 112

def to_s
  normalize
  "#{@mantissa}×10#{superscript(@exponent)}"
end