Class: Fixed
- Inherits:
-
Object
- Object
- Fixed
- Includes:
- Comparable
- Defined in:
- lib/fixed.rb,
lib/fixed/version.rb
Constant Summary collapse
- VERSION =
"1.1.0"
Instance Attribute Summary collapse
-
#fractions ⇒ Object
readonly
——- helpers ————————————————-.
Class Method Summary collapse
- .from_fractions(fractions) ⇒ Object
- .from_number(number) ⇒ Object
- .from_snapshot(arg, options) ⇒ Object
- .parse(str) ⇒ Object
- .smallest ⇒ Object
- .zero ⇒ Object
Instance Method Summary collapse
- #*(number) ⇒ Object
-
#+(number) ⇒ Object
——- arithmetics ———————————————-.
- #-(number) ⇒ Object
- #-@ ⇒ Object
- #/(number) ⇒ Object
-
#<=>(number) ⇒ Object
——- comparing ———————————————–.
- #==(number) ⇒ Object
- #abs ⇒ Object
- #format(precision = 8) ⇒ Object
-
#initialize(fractions) ⇒ Fixed
constructor
A new instance of Fixed.
-
#inspect ⇒ Object
——- printing ————————————————.
- #negative? ⇒ Boolean
- #positive? ⇒ Boolean
- #pretty_format(precision = 8) ⇒ Object
- #split(*numbers) ⇒ Object
- #to_fixed ⇒ Object
-
#to_json(state) ⇒ Object
——- serialization ——————————————-.
- #to_s(precision = 8) ⇒ Object
- #zero? ⇒ Boolean
Constructor Details
#initialize(fractions) ⇒ Fixed
Returns a new instance of Fixed.
34 35 36 37 38 |
# File 'lib/fixed.rb', line 34 def initialize(fractions) raise unless Integer === fractions @fractions = fractions freeze end |
Instance Attribute Details
#fractions ⇒ Object (readonly)
——- helpers ————————————————-
188 189 190 |
# File 'lib/fixed.rb', line 188 def fractions @fractions end |
Class Method Details
.from_fractions(fractions) ⇒ Object
48 49 50 |
# File 'lib/fixed.rb', line 48 def self.from_fractions(fractions) new fractions end |
.from_number(number) ⇒ Object
44 45 46 |
# File 'lib/fixed.rb', line 44 def self.from_number(number) new number_as_fractions(number) end |
.from_snapshot(arg, options) ⇒ Object
181 182 183 |
# File 'lib/fixed.rb', line 181 def self.from_snapshot(arg, ) String === arg ? self.parse(arg) : arg end |
.parse(str) ⇒ Object
40 41 42 |
# File 'lib/fixed.rb', line 40 def self.parse(str) new string_as_fractions(str) end |
.smallest ⇒ Object
52 53 54 |
# File 'lib/fixed.rb', line 52 def self.smallest new 1 end |
.zero ⇒ Object
56 57 58 |
# File 'lib/fixed.rb', line 56 def self.zero new 0 end |
Instance Method Details
#*(number) ⇒ Object
70 71 72 73 74 75 |
# File 'lib/fixed.rb', line 70 def *(number) make(division_with_rounding( self.fractions * number.fractions, 1000000000000000000, )) end |
#+(number) ⇒ Object
——- arithmetics ———————————————-
62 63 64 |
# File 'lib/fixed.rb', line 62 def +(number) make(self.fractions + number.fractions) end |
#-(number) ⇒ Object
66 67 68 |
# File 'lib/fixed.rb', line 66 def -(number) make(self.fractions - number.fractions) end |
#-@ ⇒ Object
84 85 86 |
# File 'lib/fixed.rb', line 84 def -@ make(-self.fractions) end |
#/(number) ⇒ Object
77 78 79 80 81 82 |
# File 'lib/fixed.rb', line 77 def /(number) make(division_with_rounding( 1000000000000000000 * self.fractions, number.fractions, )) end |
#<=>(number) ⇒ Object
——- comparing ———————————————–
119 120 121 122 |
# File 'lib/fixed.rb', line 119 def <=>(number) return nil unless Fixed === number self.fractions <=> number.fractions end |
#==(number) ⇒ Object
124 125 126 |
# File 'lib/fixed.rb', line 124 def ==(number) Fixed === number && self.fractions == number.fractions end |
#abs ⇒ Object
88 89 90 |
# File 'lib/fixed.rb', line 88 def abs make(self.fractions.abs) end |
#format(precision = 8) ⇒ Object
155 156 157 158 159 160 161 162 |
# File 'lib/fixed.rb', line 155 def format(precision = 8) raise "expected 1..18, got #{precision.inspect}" unless (0..18) === precision rounded_fractions = division_with_rounding(@fractions, 10 ** (18 - precision)) str = rounded_fractions.abs.to_s.rjust(precision + 1, ?0) str.insert(-1 - precision, ?.) if precision > 0 "#{?- if @fractions < 0}#{str}#{?* if @fractions != 0 && str =~ /^[-0\.]*$/}" end |
#inspect ⇒ Object
——- printing ————————————————
143 144 145 146 147 148 149 |
# File 'lib/fixed.rb', line 143 def inspect if @fractions >= 0 @fractions.to_s.rjust(19, ?0).insert(-19, ?.) else "-#{@fractions.abs.to_s.rjust(19, ?0).insert(-19, ?.)}" end end |
#negative? ⇒ Boolean
128 129 130 |
# File 'lib/fixed.rb', line 128 def negative? @fractions < 0 end |
#positive? ⇒ Boolean
132 133 134 |
# File 'lib/fixed.rb', line 132 def positive? @fractions > 0 end |
#pretty_format(precision = 8) ⇒ Object
164 165 166 167 168 169 170 171 172 |
# File 'lib/fixed.rb', line 164 def pretty_format(precision = 8) str = format(precision).dup stop = negative? ? 4 : 3 n = str.index('.') || str.length str.insert(n -= 3, ',') while n > stop return str end |
#split(*numbers) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/fixed.rb', line 92 def split(*numbers) ratios = numbers.map(&:to_fixed) raise ArgumentError if ratios.any?(&:negative?) raise ArgumentError if ratios.all?(&:zero?) # This method ensures that the calculated portions add up to the original # value and that no eps are lost due to rounding errors or other issues. remainder = ratios.reduce(:+) number = self ratios.map do |ratio| next Fixed.zero if remainder.zero? part = make(division_with_rounding( number.fractions * ratio.fractions, remainder.fractions, )) remainder -= ratio number -= part part end end |
#to_fixed ⇒ Object
190 191 192 |
# File 'lib/fixed.rb', line 190 def to_fixed self end |
#to_json(state) ⇒ Object
——- serialization ——————————————-
177 178 179 |
# File 'lib/fixed.rb', line 177 def to_json(state) inspect.to_json(state) end |
#to_s(precision = 8) ⇒ Object
151 152 153 |
# File 'lib/fixed.rb', line 151 def to_s(precision = 8) format(precision) end |
#zero? ⇒ Boolean
136 137 138 |
# File 'lib/fixed.rb', line 136 def zero? @fractions == 0 end |