large_binomials 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|