numscaler 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 331c09c6168e5869643abc1cb61b2add72653db9
4
+ data.tar.gz: 160bedb49e76c394081108b17d6b8b5a39305f34
5
+ SHA512:
6
+ metadata.gz: a586ebb9b32110e06ad3f10ab6618381c946c10416801dc62057f9aef4ed4e530f960a31328a11bbc2370d6e31b3278e8714fd14a79848096bcbd2f1325c3771
7
+ data.tar.gz: 3af7b7301e3068832b98d05fe225507b601cff23718592e1fe07e17b4eadd6a198f228fb9c9f2bb5cfc7631308fa5f97b168078d3e7d6f0d28a5b530f80b1564
data/.document ADDED
@@ -0,0 +1,2 @@
1
+ -
2
+ LICENSE.txt
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ doc/
2
+ pkg/
3
+ .yardoc/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --colour
data/.yardopts ADDED
@@ -0,0 +1,5 @@
1
+ --title "NumScaler Documentation"
2
+ --markup markdown
3
+ --charset utf-8
4
+ --protected
5
+ --private
data/LICENSE.txt ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2014, Piotr S. Staszewski
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ 2. Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # NumScaler
2
+
3
+ * [Homepage](https://github.com/drbig/numscaler)
4
+ * [Documentation](http://rubydoc.info/gems/numscaler/frames)
5
+
6
+ ## Description
7
+
8
+ NumScaler will convert for you numbers between ranges using simple linear
9
+ interpolation. In other words it will scale a number form its source range to a
10
+ corresponding number within the target range. And vice-versa.
11
+
12
+ It has three clamping modes that are applied to the input number before
13
+ conversion, and only if that number is outside its range:
14
+
15
+ * `:strict` - will raise an exception (*default*)
16
+ * `:clamp` - will cut the number at the edges of the range (e.g. to min or
17
+ max)
18
+ * `:cycle` - will treat the range as circular (think `number % range`)
19
+
20
+ It should work correctly for any combination of Integer and Float ranges (note
21
+ that you can't mix numeric types within a single range, as it doesn't make much
22
+ sense). It expects common-sense on your part, so trying to use it with empty
23
+ ranges (e.g. `0..0`) is left as undefined (though it might work just as you
24
+ expect, or not).
25
+
26
+ All calculations are done internally on `Float`s so there will be inevitable
27
+ rounding errors. My tests show that the precision is within 14 decimal places,
28
+ and therefore that is the default rounding.
29
+
30
+ There is a pretty brute-force test suite. Should work with any Ruby version.
31
+
32
+ ## Examples
33
+
34
+ Install and run pry/irb:
35
+
36
+ $ gem install numscaler
37
+ $ pry
38
+
39
+ Simple Integer - Integer conversion:
40
+
41
+ [1] pry(main)> require 'numscaler'
42
+ [2] pry(main)> iti = NumScaler.new(0..15, 0..256)
43
+ [3] pry(main)> iti.from(0)
44
+ => 0
45
+ [4] pry(main)> iti.from(7)
46
+ => 119
47
+ [5] pry(main)> iti.from(8)
48
+ => 137
49
+ [6] pry(main)> iti.to(128)
50
+ => 8
51
+ [7] pry(main)> iti.to(255)
52
+ => 15
53
+ [8] pry(main)> iti.from(-1)
54
+ ArgumentError: Number out of range
55
+
56
+ Integer - Float conversion:
57
+
58
+ [9] pry(main)> itf = NumScaler.new(0..7, 0.0..16.0)
59
+ [10] pry(main)> itf.from(2)
60
+ => 4.57142857142857
61
+ [11] pry(main)> itf.from(7)
62
+ => 16.0
63
+ [12] pry(main)> itf.to(4)
64
+ => 2
65
+ [13] pry(main)> itf.to(4.234)
66
+ => 2
67
+
68
+ Float - Float conversion:
69
+
70
+ [14] pry(main)> ftf = NumScaler.new(-2.5..2.5, -5.0..5.0)
71
+ [15] pry(main)> ftf.from(-2.0)
72
+ => -4.0
73
+ [16] pry(main)> ftf.to(-4.0)
74
+ => -2.0
75
+ [17] pry(main)> # deg - rad conversion
76
+ [18] pry(main)> ftf = NumScaler.new(0.0..180.0, 0.0..Math::PI)
77
+ [19] pry(main)> ftf.from(45.0)
78
+ => 0.78539816339745
79
+ [20] pry(main)> ftf.to(1.57079633)
80
+ => 90.0000001836389
81
+
82
+ Clamping examples:
83
+
84
+ [21] pry(main)> ftf = NumScaler.new(0.0..4.0, -2.5..2.5, :clamp)
85
+ [22] pry(main)> ftf.from(-1.0)
86
+ => -2.5
87
+ [23] pry(main)> ftf.from(5.0)
88
+ => 2.5
89
+ [24] pry(main)> ftf.to(15.0)
90
+ => 4.0
91
+
92
+ [25] pry(main)> ftf = NumScaler.new(0.0..4.0, -2.5..2.5, :cycle)
93
+ [26] pry(main)> ftf.from(-1.0)
94
+ => 1.25
95
+ [27] pry(main)> ftf.from(5.0)
96
+ => -1.25
97
+ [28] pry(main)> ftf.to(15.0)
98
+ => 2.0
99
+
100
+ ## Copyright
101
+
102
+ Copyright (c) 2014 Piotr S. Staszewski
103
+
104
+ Absolutely no warranty. See {file:LICENSE.txt} for details.
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+
6
+ begin
7
+ gem 'rubygems-tasks', '~> 0.2'
8
+ require 'rubygems/tasks'
9
+
10
+ Gem::Tasks.new
11
+ rescue LoadError => e
12
+ warn e.message
13
+ warn "Run `gem install rubygems-tasks` to install Gem::Tasks."
14
+ end
15
+
16
+ begin
17
+ gem 'rspec', '~> 2.4'
18
+ require 'rspec/core/rake_task'
19
+
20
+ RSpec::Core::RakeTask.new
21
+ rescue LoadError => e
22
+ task :spec do
23
+ abort "Please run `gem install rspec` to install RSpec."
24
+ end
25
+ end
26
+
27
+ task :test => :spec
28
+ task :default => :spec
29
+
30
+ begin
31
+ gem 'yard', '~> 0.8'
32
+ require 'yard'
33
+
34
+ YARD::Rake::YardocTask.new
35
+ rescue LoadError => e
36
+ task :yard do
37
+ abort "Please run `gem install yard` to install YARD."
38
+ end
39
+ end
40
+ task :doc => :yard
data/lib/numscaler.rb ADDED
@@ -0,0 +1,87 @@
1
+ # encoding: utf-8
2
+
3
+ # See {file:README.md} for practical examples.
4
+ class NumScaler
5
+ # NumScaler version string
6
+ VERSION = '0.0.4'
7
+ # Epsilon defines rounding precision
8
+ EPSILON = 14
9
+ # Available clamping modes
10
+ MODES = [:strict, :cycle, :clamp]
11
+
12
+ # Current clamping modes:
13
+ #
14
+ # * `:strict` - raise ArgumentError for out-of-range number (*default*)
15
+ # * `:clamp` - clamp number to source range
16
+ # * `:cycle` - treat range as a circle of values
17
+ #
18
+ # Precision defines number of significant decimal digits for rounding.
19
+ #
20
+ # @param from [Range] source range
21
+ # @param to [Range] target range
22
+ # @param mode [Symbol] clamping mode
23
+ # @param precision [Float] rounding precision
24
+ def initialize(from, to, mode = MODES.first, precision = EPSILON)
25
+ raise ArgumentError, 'Unknown mode' unless MODES.member? mode
26
+ raise ArgumentError, 'Precision out of ranger' unless precision > 0
27
+
28
+ @mode = mode
29
+ @prec = precision
30
+
31
+ @src = { :orig => from.min,
32
+ :range => from.max.to_f - from.min.to_f,
33
+ :max => from.max.to_f,
34
+ :min => from.min.to_f }
35
+ @tgt = { :orig => to.min,
36
+ :range => to.max.to_f - to.min.to_f,
37
+ :max => to.max.to_f,
38
+ :min => to.min.to_f }
39
+ end
40
+
41
+ # Convert number from source to target
42
+ #
43
+ # @param num [Numeric]
44
+ # @return [Numeric]
45
+ def from(num); calc(num, @src, @tgt); end
46
+
47
+ # Convert number from target to source
48
+ #
49
+ # @param num [Numeric]
50
+ # @return [Numeric]
51
+ def to(num); calc(num, @tgt, @src); end
52
+
53
+ private
54
+ # Perform actual calculation:
55
+ #
56
+ # 1. First check and if necessary apply clamping
57
+ # 1. Then convert between ranges
58
+ # 1. Lastly check how to exactly return the result and do so
59
+ #
60
+ # @param num [Numeric] number to convert
61
+ # @param a [Hash] source range data
62
+ # @param b [Hash] target range data
63
+ # @return [Numeric]
64
+ def calc(num, a, b)
65
+ num = num.to_f
66
+
67
+ unless num.between?(a[:min], a[:max])
68
+ num = case @mode
69
+ when :cycle
70
+ ((num - a[:min]) % (a[:range])) + a[:min]
71
+ when :clamp
72
+ num > a[:max] ? a[:max] : a[:min]
73
+ when :strict
74
+ raise ArgumentError, 'Number out of range'
75
+ end
76
+ end
77
+
78
+ res = (((num - a[:min]) * b[:range]) / a[:range]) + b[:min]
79
+
80
+ case b[:orig]
81
+ when Integer
82
+ res.round
83
+ else
84
+ res.round(@prec)
85
+ end
86
+ end
87
+ end
data/numscaler.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../lib/numscaler', __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = 'numscaler'
7
+ gem.version = NumScaler::VERSION
8
+ gem.date = Time.now
9
+
10
+ gem.summary = 'Easily convert numbers between different ranges'
11
+ gem.description = 'Convert numbers e.g. between 0.0 - 1.0 and 0.0 - Math::PI and vice-versa.'
12
+ gem.license = 'BSD'
13
+ gem.authors = ['Piotr S. Staszewski']
14
+ gem.email = 'p.staszewski@gmail.com'
15
+ gem.homepage = 'https://github.com/drbig/numscaler'
16
+
17
+ gem.files = `git ls-files`.split("\n")
18
+ gem.test_files = gem.files.grep(%r{^spec/})
19
+ gem.require_paths = ['lib']
20
+
21
+ gem.add_development_dependency 'rspec', '~> 2.4'
22
+ gem.add_development_dependency 'rubygems-tasks', '~> 0.2'
23
+ gem.add_development_dependency 'yard', '~> 0.8'
24
+ end
@@ -0,0 +1,183 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rspec'
4
+ require 'numscaler'
5
+
6
+ describe NumScaler do
7
+ it 'should have a VERSION constant' do
8
+ NumScaler::VERSION.should_not be_empty
9
+ end
10
+
11
+ it 'should have an EPSILON constant' do
12
+ NumScaler::EPSILON.should > 0
13
+ end
14
+
15
+ it 'should define clamping MODES' do
16
+ NumScaler::MODES.should_not be_empty
17
+ end
18
+
19
+ it 'should check arguments' do
20
+ lambda {
21
+ NumScaler.new(1..8, 16..32, :nonext)
22
+ }.should raise_error(ArgumentError)
23
+ end
24
+
25
+ context 'should work with Integer <=> Integer ranges and' do
26
+ it 'should convert from' do
27
+ scaler = NumScaler.new(1..8, 16..32)
28
+
29
+ scaler.from(1).should eq 16
30
+ scaler.from(4).should eq 23
31
+ scaler.from(8).should eq 32
32
+ end
33
+
34
+ it 'should convert to' do
35
+ scaler = NumScaler.new(1..8, -32..32)
36
+
37
+ scaler.to(-32).should eq 1
38
+ scaler.to( 0).should eq 5
39
+ scaler.to( 32).should eq 8
40
+ end
41
+ end
42
+
43
+ context 'should work with Integer <=> Float ranges and' do
44
+ before(:all) do
45
+ @prec = NumScaler::EPSILON
46
+ end
47
+
48
+ it 'should convert from' do
49
+ scaler = NumScaler.new(0..15, 0.0..Math::PI)
50
+ scaler.from( 0 ).should eq 0.0
51
+ scaler.from( 7.5).should eq (Math::PI/2.0).round(@prec)
52
+ scaler.from(15 ).should eq Math::PI.round(@prec)
53
+
54
+ scaler = NumScaler.new(-15..15, 0.0..Math::PI)
55
+ scaler.from(-15).should eq 0.0
56
+ scaler.from( 0).should eq (Math::PI/2.0).round(@prec)
57
+ scaler.from( 15).should eq Math::PI.round(@prec)
58
+ end
59
+
60
+ it 'should convert to' do
61
+ scaler = NumScaler.new(0..15, 0.0..Math::PI)
62
+ scaler.to(0.0).should eq 0
63
+ scaler.to(Math::PI/2.0).should eq 7
64
+ scaler.to(Math::PI).should eq 15
65
+
66
+ scaler = NumScaler.new(-15..15, 0.0..Math::PI)
67
+ scaler.to(0.0).should eq -15
68
+ scaler.to(Math::PI/2.0).should eq 0
69
+ scaler.to(Math::PI).should eq 15
70
+ end
71
+ end
72
+
73
+ context 'should work with Float <=> Float ranges and' do
74
+ before(:all) do
75
+ @prec = NumScaler::EPSILON
76
+ end
77
+
78
+ it 'should convert from' do
79
+ scaler = NumScaler.new(0.0..256.0, 0.0..Math::PI)
80
+ scaler.from( 0.0).should eq 0.0
81
+ scaler.from( 32.0).should eq (Math::PI/8.0).round(@prec)
82
+ scaler.from( 64.0).should eq (Math::PI/4.0).round(@prec)
83
+ scaler.from(128.0).should eq (Math::PI/2.0).round(@prec)
84
+ scaler.from(256.0).should eq Math::PI.round(@prec)
85
+
86
+ scaler = NumScaler.new(0.0..256.0, -Math::PI..Math::PI)
87
+ scaler.from( 0.0).should eq -Math::PI.round(@prec)
88
+ scaler.from( 64.0).should eq (-Math::PI/2.0).round(@prec)
89
+ scaler.from(128.0).should eq 0.0
90
+ scaler.from(192.0).should eq (Math::PI/2.0).round(@prec)
91
+ scaler.from(256.0).should eq Math::PI.round(@prec)
92
+ end
93
+
94
+ it 'should convert to' do
95
+ scaler = NumScaler.new(0.0..256.0, 0.0..Math::PI)
96
+ scaler.to(0.0).should eq 0.0
97
+ scaler.to(Math::PI/8.0).should eq 32.0
98
+ scaler.to(Math::PI/4.0).should eq 64.0
99
+ scaler.to(Math::PI/2.0).should eq 128.0
100
+ scaler.to(Math::PI).should eq 256.0
101
+
102
+ scaler = NumScaler.new(0.0..256.0, -Math::PI..Math::PI)
103
+ scaler.to(-Math::PI).should eq 0.0
104
+ scaler.to(-Math::PI/2.0).should eq 64.0
105
+ scaler.to(0.0).should eq 128.0
106
+ scaler.to(Math::PI/2.0).should eq 192.0
107
+ scaler.to(Math::PI).should eq 256.0
108
+ end
109
+ end
110
+
111
+ context 'should :strict clamp properly' do
112
+ it 'with Integer ranges' do
113
+ scaler = NumScaler.new(1..8, -5..5)
114
+ lambda { scaler.from(-1) }.should raise_error ArgumentError
115
+ lambda { scaler.from( 0) }.should raise_error ArgumentError
116
+ lambda { scaler.from( 9) }.should raise_error ArgumentError
117
+ lambda { scaler.to(-6) }.should raise_error ArgumentError
118
+ lambda { scaler.to( 6) }.should raise_error ArgumentError
119
+ end
120
+
121
+ it 'with Float ranges' do
122
+ scaler = NumScaler.new(0.5..1.25, -5.0..5.0)
123
+ lambda { scaler.from(0.42 ) }.should raise_error ArgumentError
124
+ lambda { scaler.from(0.499) }.should raise_error ArgumentError
125
+ lambda { scaler.from(1.26 ) }.should raise_error ArgumentError
126
+ lambda { scaler.from(1.3 ) }.should raise_error ArgumentError
127
+ lambda { scaler.to(-5.1) }.should raise_error ArgumentError
128
+ lambda { scaler.to( 5.1) }.should raise_error ArgumentError
129
+ end
130
+ end
131
+
132
+ context 'should :clamp clamp properly' do
133
+ it 'with Integer ranges' do
134
+ scaler = NumScaler.new(1..8, -32..32, :clamp)
135
+ scaler.from(-1).should eq -32
136
+ scaler.from( 0).should eq -32
137
+ scaler.from( 9).should eq 32
138
+ scaler.to(-33).should eq 1
139
+ scaler.to( 0).should eq 5
140
+ scaler.to( 33).should eq 8
141
+ end
142
+
143
+ it 'with Float ranges' do
144
+ scaler = NumScaler.new(1.0..8.0, -32.0..32.0, :clamp)
145
+ scaler.from(0.89).should eq -32.0
146
+ scaler.from(8.01).should eq 32.0
147
+ scaler.to(-32.1).should eq 1.0
148
+ scaler.to( 32.1).should eq 8.0
149
+ end
150
+ end
151
+
152
+ context 'should :cycle clamp properly' do
153
+ it 'with Integer ranges' do
154
+ scaler = NumScaler.new(1..8, -8..-1, :cycle)
155
+ scaler.from(-2).should eq -4
156
+ scaler.from( 0).should eq -2
157
+ scaler.from( 2).should eq -7
158
+ scaler.from( 9).should eq -7
159
+ scaler.to(-9).should eq 7
160
+ scaler.to( 0).should eq 2
161
+
162
+ scaler = NumScaler.new(-5..5, 20..30, :cycle)
163
+ scaler.from(-8).should eq 27
164
+ scaler.from(-7).should eq 28
165
+ scaler.from(-6).should eq 29
166
+ scaler.from( 6).should eq 21
167
+ scaler.from( 7).should eq 22
168
+ scaler.to(18).should eq 3
169
+ scaler.to(19).should eq 4
170
+ scaler.to(31).should eq -4
171
+ scaler.to(41).should eq -4
172
+ end
173
+
174
+ it 'with Float ranges' do
175
+ scaler = NumScaler.new(-2.5..2.5, 20.0..30.0, :cycle)
176
+ scaler.from(-6.0).should eq 23.0
177
+ scaler.from(-2.0).should eq 21.0
178
+ scaler.from( 0.0).should eq 25.0
179
+ scaler.from( 3.0).should eq 21.0
180
+ scaler.from( 6.0).should eq 27.0
181
+ end
182
+ end
183
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: numscaler
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Piotr S. Staszewski
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.4'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubygems-tasks
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: yard
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.8'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.8'
55
+ description: Convert numbers e.g. between 0.0 - 1.0 and 0.0 - Math::PI and vice-versa.
56
+ email: p.staszewski@gmail.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - ".document"
62
+ - ".gitignore"
63
+ - ".rspec"
64
+ - ".yardopts"
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - lib/numscaler.rb
69
+ - numscaler.gemspec
70
+ - spec/numscaler_spec.rb
71
+ homepage: https://github.com/drbig/numscaler
72
+ licenses:
73
+ - BSD
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.2.2
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: Easily convert numbers between different ranges
95
+ test_files:
96
+ - spec/numscaler_spec.rb