large_binomials 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +674 -0
- data/README.md +82 -0
- data/Rakefile +45 -0
- data/bin/test_performance_binomial.rb +37 -0
- data/large_binomials.gemspec +37 -0
- data/lib/core_ext/integer.rb +127 -0
- data/lib/large_binomials.rb +26 -0
- data/lib/large_binomials/large_float.rb +129 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/unit/integer_spec.rb +247 -0
- data/spec/unit/large_float_spec.rb +281 -0
- metadata +62 -0
data/README.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
large_binomials
|
2
|
+
===============
|
3
|
+
|
4
|
+
This gem mixes in some general methods to calculate binomials to `Integer`. In
|
5
|
+
addition, it also mixes in some methods to calculate large binomials, with
|
6
|
+
“large” being defined as having a result greater than `Float.MAX`. The main
|
7
|
+
`Integer#binomial(k)` method is then adjusted such that when the result is less
|
8
|
+
than or equal to `Float.MAX`, an `Integer` is returned, and a
|
9
|
+
`LargeBinomials::LargeFloat` otherwise. Continuing to use `Integer` makes the
|
10
|
+
calculation of binomials more and more expensive as the result becomes larger
|
11
|
+
and larger.
|
12
|
+
|
13
|
+
Installation
|
14
|
+
------------
|
15
|
+
|
16
|
+
Do the following to install this gem:
|
17
|
+
|
18
|
+
1. Make a clone of the repository
|
19
|
+
2. Build the gem: `gem build large_binomials.gemspec`
|
20
|
+
3. Install the gem: `gem install ./large_binomials-0.9.gem`
|
21
|
+
|
22
|
+
Usage
|
23
|
+
-----
|
24
|
+
|
25
|
+
The following code (also included in the project as
|
26
|
+
`bin/test_performance_binomial.rb`) shows how to use the library:
|
27
|
+
|
28
|
+
# encoding: utf-8
|
29
|
+
#
|
30
|
+
# Test the performance of the calculation of a binomial
|
31
|
+
#
|
32
|
+
|
33
|
+
require 'benchmark'
|
34
|
+
require 'large_binomials'
|
35
|
+
|
36
|
+
puts "Going to test the performance of the calculation of a binomial."
|
37
|
+
|
38
|
+
Samples = (1 .. 3).collect{ |i| 10 ** i}.collect{ |i| [1, 2, 3, 5].collect{ |j| j * i}}.flatten
|
39
|
+
|
40
|
+
Samples.each{ |n|
|
41
|
+
[1, n/100, n/10, n/2].each { |k|
|
42
|
+
puts "#{n} C #{k}"
|
43
|
+
c = 0
|
44
|
+
time = Benchmark.realtime { c = n.binomial(k) }
|
45
|
+
puts " binomial: #{time}s (#{c})"
|
46
|
+
time = Benchmark.realtime { c = n.float_binomial_by_product_of_divisions(k) }
|
47
|
+
puts " Π(/), float: #{time}s (#{c})"
|
48
|
+
time = Benchmark.realtime { c = n.float_binomial_by_division_of_products(k) }
|
49
|
+
puts " Π/Π, float: #{time}s (#{c})"
|
50
|
+
time = Benchmark.realtime { c = n.large_float_binomial_by_product_of_divisions(k) }
|
51
|
+
puts " Π(/), LargeFloat: #{time}s (#{c})"
|
52
|
+
time = Benchmark.realtime { c = n.large_float_binomial_by_division_of_products(k) }
|
53
|
+
puts " Π/Π, LargeFloat: #{time}s (#{c})"
|
54
|
+
time = Benchmark.realtime { c = n.binomial_by_division_of_parallel_products(k) }
|
55
|
+
puts " ∥Π/∥Π, integer: #{time}s (#{c})"
|
56
|
+
time = Benchmark.realtime { c = n.binomial_by_division_of_products(k) }
|
57
|
+
puts " Π/Π, integer: #{time}s (#{c})"
|
58
|
+
time = Benchmark.realtime { c = n.binomial_by_product_of_divisions(k) }
|
59
|
+
puts " Π(/), integer: #{time}s (#{c})"
|
60
|
+
time = Benchmark.realtime { c = n.binomial_by_pascals_triangle(k) }
|
61
|
+
puts " ∑, integer: #{time}s (#{c})"
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
License
|
66
|
+
-------
|
67
|
+
|
68
|
+
Library to calculate large binomials
|
69
|
+
Copyright (C) 2013 Filip van Laenen <f.a.vanlaenen@ieee.org>
|
70
|
+
|
71
|
+
This program is free software: you can redistribute it and/or modify
|
72
|
+
it under the terms of the GNU General Public License as published by
|
73
|
+
the Free Software Foundation, either version 3 of the License, or
|
74
|
+
(at your option) any later version.
|
75
|
+
|
76
|
+
This program is distributed in the hope that it will be useful,
|
77
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
78
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
79
|
+
GNU General Public License for more details.
|
80
|
+
|
81
|
+
You should have received a copy of the GNU General Public License
|
82
|
+
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
data/Rakefile
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# Ruby Library to Calculate Large Binomials
|
2
|
+
# Copyright © 2013 Filip van Laenen <f.a.vanlaenen@ieee.org>
|
3
|
+
#
|
4
|
+
# This file is part of the Ruby Library to Calculate Large Binomials.
|
5
|
+
#
|
6
|
+
# The Ruby Library to Calculate Large Binomials is free software: you can
|
7
|
+
# redistribute it and/or modify it under the terms of the GNU General Public
|
8
|
+
# License as published by the Free Software Foundation, either version 3 of the
|
9
|
+
# License, or (at your option) any later version.
|
10
|
+
#
|
11
|
+
# The Ruby Library to Calculate Large Binomials is distributed in the hope that
|
12
|
+
# it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
13
|
+
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
14
|
+
# Public License for more details.
|
15
|
+
#
|
16
|
+
# You can find a copy of the GNU General Public License in /LICENSE
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'rspec/core/rake_task'
|
20
|
+
|
21
|
+
desc 'Default: run specs.'
|
22
|
+
task :default => :spec
|
23
|
+
|
24
|
+
desc 'Run specs'
|
25
|
+
RSpec::Core::RakeTask.new do |t|
|
26
|
+
t.pattern = "./spec/**/*_spec.rb"
|
27
|
+
end
|
28
|
+
|
29
|
+
def find_integer_methods
|
30
|
+
require_relative 'lib/core_ext/integer'
|
31
|
+
integer_methods = Integer.instance_methods(false)
|
32
|
+
integer_methods.select!{ | m | 1.method(m).source_location != nil }
|
33
|
+
integer_methods.select!{ | m | 1.method(m).source_location[0].include? 'large_binomials'}
|
34
|
+
integer_methods.collect{ | m | "::Integer##{m}"}
|
35
|
+
end
|
36
|
+
|
37
|
+
desc 'Run Mutant'
|
38
|
+
task :mutant do
|
39
|
+
require 'mutant'
|
40
|
+
find_integer_methods
|
41
|
+
status = Mutant::CLI.run(['::LargeBinomials*', find_integer_methods, '--rspec-unit'].flatten)
|
42
|
+
if status.nonzero?
|
43
|
+
abort 'Mutant task is not successful'
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
#
|
4
|
+
# Test the performance of the calculation of a binomial
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'benchmark'
|
8
|
+
require 'large_binomials'
|
9
|
+
|
10
|
+
puts "Going to test the performance of the calculation of a binomial."
|
11
|
+
|
12
|
+
Samples = (1 .. 3).collect{ |i| 10 ** i}.collect{ |i| [1, 2, 3, 5].collect{ |j| j * i}}.flatten
|
13
|
+
|
14
|
+
Samples.each{ |n|
|
15
|
+
[1, n/100, n/10, n/2].each { |k|
|
16
|
+
puts "#{n} C #{k}"
|
17
|
+
c = 0
|
18
|
+
time = Benchmark.realtime { c = n.binomial(k) }
|
19
|
+
puts " binomial: #{time}s (#{c})"
|
20
|
+
time = Benchmark.realtime { c = n.float_binomial_by_product_of_divisions(k) }
|
21
|
+
puts " Π(/), float: #{time}s (#{c})"
|
22
|
+
time = Benchmark.realtime { c = n.float_binomial_by_division_of_products(k) }
|
23
|
+
puts " Π/Π, float: #{time}s (#{c})"
|
24
|
+
time = Benchmark.realtime { c = n.large_float_binomial_by_product_of_divisions(k) }
|
25
|
+
puts " Π(/), LargeFloat: #{time}s (#{c})"
|
26
|
+
time = Benchmark.realtime { c = n.large_float_binomial_by_division_of_products(k) }
|
27
|
+
puts " Π/Π, LargeFloat: #{time}s (#{c})"
|
28
|
+
time = Benchmark.realtime { c = n.binomial_by_division_of_parallel_products(k) }
|
29
|
+
puts " ∥Π/∥Π, integer: #{time}s (#{c})"
|
30
|
+
time = Benchmark.realtime { c = n.binomial_by_division_of_products(k) }
|
31
|
+
puts " Π/Π, integer: #{time}s (#{c})"
|
32
|
+
time = Benchmark.realtime { c = n.binomial_by_product_of_divisions(k) }
|
33
|
+
puts " Π(/), integer: #{time}s (#{c})"
|
34
|
+
time = Benchmark.realtime { c = n.binomial_by_pascals_triangle(k) }
|
35
|
+
puts " ∑, integer: #{time}s (#{c})"
|
36
|
+
}
|
37
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#
|
3
|
+
# Ruby Library to Calculate Large Binomials
|
4
|
+
# Copyright © 2013 Filip van Laenen <f.a.vanlaenen@ieee.org>
|
5
|
+
#
|
6
|
+
# This file is part of the Ruby Library to Calculate Large Binomials.
|
7
|
+
#
|
8
|
+
# The Ruby Library to Calculate Large Binomials is free software: you can
|
9
|
+
# redistribute it and/or modify it under the terms of the GNU General Public
|
10
|
+
# License as published by the Free Software Foundation, either version 3 of the
|
11
|
+
# License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# The Ruby Library to Calculate Large Binomials is distributed in the hope that
|
14
|
+
# it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
15
|
+
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
16
|
+
# Public License for more details.
|
17
|
+
#
|
18
|
+
# You can find a copy of the GNU General Public License in /LICENSE
|
19
|
+
#
|
20
|
+
|
21
|
+
Gem::Specification.new do |gem|
|
22
|
+
gem.name = 'large_binomials'
|
23
|
+
gem.version = '1.0.0'
|
24
|
+
gem.authors = [ 'Filip van Laenen' ]
|
25
|
+
gem.email = [ 'f.a.vanlaenen@ieee.org' ]
|
26
|
+
|
27
|
+
gem.description = 'Large binomials'
|
28
|
+
gem.summary = 'Library to calculate large binomials'
|
29
|
+
gem.homepage = 'https://github.com/filipvanlaenen/large_binomials'
|
30
|
+
gem.license = 'GPL'
|
31
|
+
|
32
|
+
gem.require_paths = [ 'lib' ]
|
33
|
+
gem.files = `git ls-files`.split("\n")
|
34
|
+
gem.test_files = `git ls-files -- spec`.split("\n")
|
35
|
+
gem.extra_rdoc_files = %w[LICENSE README.md]
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Ruby Library to Calculate Large Binomials
|
4
|
+
# Copyright © 2013 Filip van Laenen <f.a.vanlaenen@ieee.org>
|
5
|
+
#
|
6
|
+
# This file is part of the Ruby Library to Calculate Large Binomials.
|
7
|
+
#
|
8
|
+
# The Ruby Library to Calculate Large Binomials is free software: you can
|
9
|
+
# redistribute it and/or modify it under the terms of the GNU General Public
|
10
|
+
# License as published by the Free Software Foundation, either version 3 of the
|
11
|
+
# License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# The Ruby Library to Calculate Large Binomials is distributed in the hope that
|
14
|
+
# it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
15
|
+
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
16
|
+
# Public License for more details.
|
17
|
+
#
|
18
|
+
# You can find a copy of the GNU General Public License in /LICENSE
|
19
|
+
#
|
20
|
+
|
21
|
+
class Integer
|
22
|
+
|
23
|
+
def to_lf
|
24
|
+
LargeBinomials::LargeFloat.new(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
def binomial(k)
|
28
|
+
binomial = breaking_binomial_by_product_of_divisions(k)
|
29
|
+
if binomial == nil
|
30
|
+
large_float_binomial_by_product_of_divisions(k)
|
31
|
+
else
|
32
|
+
binomial
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Copied from http://rosettacode.org/wiki/Evaluate_binomial_coefficients#Ruby (on 7 June 2013)
|
37
|
+
def binomial_by_product_of_divisions(k)
|
38
|
+
(0...k).inject(1) do |m,i|
|
39
|
+
(m * (self - i)) / (i + 1)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Breaking version of binomial_by_product_of_divisions
|
44
|
+
def breaking_binomial_by_product_of_divisions(k)
|
45
|
+
(0...k).inject(1) do |m,i|
|
46
|
+
if m > Float::MAX
|
47
|
+
return nil
|
48
|
+
end
|
49
|
+
(m * (self - i)) / (i + 1)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# LargeFloat version of binomial_by_product_of_divisions
|
54
|
+
def large_float_binomial_by_product_of_divisions(k)
|
55
|
+
(0...k).inject(1.to_lf) do |m,i|
|
56
|
+
(m * (self - i)) / (i + 1)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# Float version of binomial_by_product_of_divisions
|
61
|
+
def float_binomial_by_product_of_divisions(k)
|
62
|
+
(0...k).inject(1.to_f) do |m,i|
|
63
|
+
(m * (self - i)) / (i + 1)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# From http://rosettacode.org/wiki/Evaluate_binomial_coefficients#Ruby (on 7 June 2013)
|
68
|
+
def binomial_by_division_of_products(k)
|
69
|
+
# n!/(n-k)!
|
70
|
+
pTop = (self-k+1 .. self).inject(1, &:*)
|
71
|
+
# k!
|
72
|
+
pBottom = (2 .. k).inject(1, &:*)
|
73
|
+
pTop / pBottom
|
74
|
+
end
|
75
|
+
|
76
|
+
# Parallel version of binomial_by_division_of_products
|
77
|
+
# Note that threads in Ruby 1.9 don't spread over multiple processors, so
|
78
|
+
# due to context switching this parallel version will often be a bit slower
|
79
|
+
# than the sequential one.
|
80
|
+
def binomial_by_division_of_parallel_products(k)
|
81
|
+
# n!/(n-k)!
|
82
|
+
top_thread = Thread.new do
|
83
|
+
Thread.current[:output] = (self-k+1 .. self).inject(1, &:*)
|
84
|
+
end
|
85
|
+
# k!
|
86
|
+
bottom_thread = Thread.new do
|
87
|
+
Thread.current[:output] = (2 .. k).inject(1, &:*)
|
88
|
+
end
|
89
|
+
top_thread.join
|
90
|
+
bottom_thread.join
|
91
|
+
top_thread[:output] / bottom_thread[:output]
|
92
|
+
end
|
93
|
+
|
94
|
+
# LargeFloat version of binomial_by_division_of_products
|
95
|
+
def large_float_binomial_by_division_of_products(k)
|
96
|
+
# n!/(n-k)!
|
97
|
+
pTop = (self-k+1 .. self).inject(1.to_lf, &:*)
|
98
|
+
# k!
|
99
|
+
pBottom = (2 .. k).inject(1.to_lf, &:*)
|
100
|
+
pTop / pBottom
|
101
|
+
end
|
102
|
+
|
103
|
+
# Float version of binomial_by_division_of_products
|
104
|
+
def float_binomial_by_division_of_products(k)
|
105
|
+
# n!/(n-k)!
|
106
|
+
pTop = (self-k+1 .. self).inject(1.to_f, &:*)
|
107
|
+
# k!
|
108
|
+
pBottom = (2 .. k).inject(1.to_f, &:*)
|
109
|
+
pTop / pBottom
|
110
|
+
end
|
111
|
+
|
112
|
+
# Copied from http://www.brpreiss.com/books/opus8/html/page459.html (on 7 June 2013)
|
113
|
+
def binomial_by_pascals_triangle(k)
|
114
|
+
b = []
|
115
|
+
b[0] = 1
|
116
|
+
for i in 1 .. self
|
117
|
+
b[i] = 1
|
118
|
+
j = i - 1
|
119
|
+
while j > 0
|
120
|
+
b[j] += b[j - 1]
|
121
|
+
j -= 1
|
122
|
+
end
|
123
|
+
end
|
124
|
+
b[k]
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Ruby Library to Calculate Large Binomials
|
4
|
+
# Copyright © 2013 Filip van Laenen <f.a.vanlaenen@ieee.org>
|
5
|
+
#
|
6
|
+
# This file is part of the Ruby Library to Calculate Large Binomials.
|
7
|
+
#
|
8
|
+
# The Ruby Library to Calculate Large Binomials is free software: you can
|
9
|
+
# redistribute it and/or modify it under the terms of the GNU General Public
|
10
|
+
# License as published by the Free Software Foundation, either version 3 of the
|
11
|
+
# License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# The Ruby Library to Calculate Large Binomials is distributed in the hope that
|
14
|
+
# it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
15
|
+
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
16
|
+
# Public License for more details.
|
17
|
+
#
|
18
|
+
# You can find a copy of the GNU General Public License in /LICENSE
|
19
|
+
#
|
20
|
+
|
21
|
+
# Library namespace
|
22
|
+
module LargeBinomials
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'core_ext/integer'
|
26
|
+
require 'large_binomials/large_float'
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# Ruby Library to Calculate Large Binomials
|
4
|
+
# Copyright © 2013 Filip van Laenen <f.a.vanlaenen@ieee.org>
|
5
|
+
#
|
6
|
+
# This file is part of the Ruby Library to Calculate Large Binomials.
|
7
|
+
#
|
8
|
+
# The Ruby Library to Calculate Large Binomials is free software: you can
|
9
|
+
# redistribute it and/or modify it under the terms of the GNU General Public
|
10
|
+
# License as published by the Free Software Foundation, either version 3 of the
|
11
|
+
# License, or (at your option) any later version.
|
12
|
+
#
|
13
|
+
# The Ruby Library to Calculate Large Binomials is distributed in the hope that
|
14
|
+
# it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
15
|
+
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
16
|
+
# Public License for more details.
|
17
|
+
#
|
18
|
+
# You can find a copy of the GNU General Public License in /LICENSE
|
19
|
+
#
|
20
|
+
|
21
|
+
module LargeBinomials
|
22
|
+
class LargeFloat
|
23
|
+
include Comparable
|
24
|
+
|
25
|
+
attr_accessor :exponent, :mantissa
|
26
|
+
|
27
|
+
def initialize(m, e = 0)
|
28
|
+
@mantissa = m.to_f
|
29
|
+
@exponent = e
|
30
|
+
end
|
31
|
+
|
32
|
+
def clone
|
33
|
+
LargeFloat.new(@mantissa, @exponent)
|
34
|
+
end
|
35
|
+
|
36
|
+
def normalize
|
37
|
+
unless @mantissa == 0
|
38
|
+
normalization = Math.log10(@mantissa).floor
|
39
|
+
@mantissa /= 10 ** normalization
|
40
|
+
@exponent += normalization
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def *(x)
|
45
|
+
if (x.instance_of? LargeFloat)
|
46
|
+
multiply_with_large_float(x)
|
47
|
+
else
|
48
|
+
multiply_with_numeric(x)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def multiply_with_large_float(lf)
|
53
|
+
product = self * lf.mantissa
|
54
|
+
product.exponent += lf.exponent
|
55
|
+
product
|
56
|
+
end
|
57
|
+
|
58
|
+
def multiply_with_numeric(i)
|
59
|
+
product = clone
|
60
|
+
new_mantissa = product.mantissa * i
|
61
|
+
if new_mantissa == Float::INFINITY
|
62
|
+
product.normalize
|
63
|
+
end
|
64
|
+
product.mantissa *= i
|
65
|
+
product
|
66
|
+
end
|
67
|
+
|
68
|
+
def /(x)
|
69
|
+
if (x.instance_of? LargeFloat)
|
70
|
+
divide_by_large_float(x)
|
71
|
+
else
|
72
|
+
divide_by_numeric(x)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def divide_by_large_float(lf)
|
77
|
+
quotient = self / lf.mantissa
|
78
|
+
quotient.exponent -= lf.exponent
|
79
|
+
quotient
|
80
|
+
end
|
81
|
+
|
82
|
+
def divide_by_numeric(n)
|
83
|
+
quotient = clone
|
84
|
+
quotient.mantissa /= n
|
85
|
+
quotient
|
86
|
+
end
|
87
|
+
|
88
|
+
def new_mantissa_for_addition(lf)
|
89
|
+
@mantissa + lf.mantissa * 10 ** (lf.exponent - @exponent)
|
90
|
+
end
|
91
|
+
|
92
|
+
def +(lf)
|
93
|
+
if self < lf
|
94
|
+
lf + self
|
95
|
+
else
|
96
|
+
LargeFloat.new(new_mantissa_for_addition(lf), @exponent)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def superscript(i)
|
101
|
+
s = i.to_s
|
102
|
+
s = s.gsub(/1/, '¹')
|
103
|
+
s = s.gsub(/2/, '²')
|
104
|
+
s = s.gsub(/3/, '³')
|
105
|
+
s = s.gsub(/4/, '⁴')
|
106
|
+
s = s.gsub(/5/, '⁵')
|
107
|
+
s = s.gsub(/6/, '⁶')
|
108
|
+
s = s.gsub(/7/, '⁷')
|
109
|
+
s = s.gsub(/8/, '⁸')
|
110
|
+
s = s.gsub(/9/, '⁹')
|
111
|
+
s.gsub(/0/, '⁰')
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_s
|
115
|
+
normalize
|
116
|
+
"#{@mantissa}×10#{superscript(@exponent)}"
|
117
|
+
end
|
118
|
+
|
119
|
+
def <=>(lf)
|
120
|
+
normalize
|
121
|
+
lf.normalize
|
122
|
+
if @exponent == lf.exponent
|
123
|
+
@mantissa - lf.mantissa
|
124
|
+
else
|
125
|
+
@exponent - lf.exponent
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|