pretty_round 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 81b0efd5424a3bcdeacf134caec4d82801f241ab
4
- data.tar.gz: 5a3e997f35204b86c08c3e65566cfde0bdcf5389
3
+ metadata.gz: d43638c5621ed6510153ba224064c8e72a20265d
4
+ data.tar.gz: e0a4bf7bc31b3abde7ec213e0391d8f88f94b243
5
5
  SHA512:
6
- metadata.gz: e7873f9c7ee8c9e129bf565ed0938421892bad9fecfa8b473d20e1bfe6be0e91be532a367e18c674ed54c1d12a032dc6e5cb38924e6192bdd88d98ba3b3e76fd
7
- data.tar.gz: de9fa9b940b5246a221e2be45485a49cc6fe9051b04a60b209d9cab2ea17979708384981b5ee0c6e1323175d3eafe448ee91a293b987b815b9fa214331f779f1
6
+ metadata.gz: e6abde717b245bdc2eba773eb7cc7fa09f221dbc09803fe6ee96376f812eb7fea0de0e3521a654e32f4308171f879ba7f926b2baa68f358ce83b37e5098f5834
7
+ data.tar.gz: 2d607ad3107cc7890bedac69a1e96c7d8d774c3b99679b64646a8855986d0ed7f21fb6ef4f51cc2e154575f2920d6b9a86f70283b6c7863003b8fc69f3661715
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ruby-pretty-round
2
2
  ================
3
- This gem add useful numerical rounding methods to `Numeric` class as shown below...
3
+ This gem add useful numerical rounding methods to `Numeric` class as shown below.
4
4
  - round to nearest multiple
5
5
  - round with significant digits
6
6
 
@@ -16,7 +16,7 @@ require "pretty_round"
16
16
  x = 123.456
17
17
 
18
18
  # round with precision
19
- x.roundup(2) #=> 123.46
19
+ x.roundup #=> 124
20
20
  x.rounddown(2) #=> 123.45
21
21
 
22
22
  # round to nearest multiple
@@ -36,59 +36,54 @@ x.sround(5) #=> 123.46
36
36
 
37
37
  Rounding direction
38
38
  ================
39
- Also, try to run `examples/example.rb`
39
+ - `#*ceil` / `#*floor`: These methods round to the positive / negative infinity direction. Its behavior is same as built-in `#ceil`, `#floor`.
40
+ - `#*roundup` / `#*rounddown`: These methods round to far from / near to 0 direction.
41
+ - `#*round`: These methods round off the absolute value, does not round even. Its behavior is same as built-in `#round`.
42
+ - `#*truncate`: These methods are alias of `#*rounddown`.
40
43
 
41
- `#mceil`, `#sceil`
42
- ----------------
43
- These methods round up to the positive infinity direction.
44
- Its behavior is same as built-in #ceil.
45
- ```rb
46
- 1.9.mceil(1) #=> 2
47
- 1.1.mceil(1) #=> 2
48
- -1.1.mceil(1) #=> -1
49
- -1.9.mceil(1) #=> -1
44
+ Result table is shown below, including ruby built-in rounding methods for comparison.
45
+ An axis of abscissas refers to the receiver and an axis of ordinates refers to the methods.
50
46
  ```
51
-
52
- `#mfloor`, `#sfloor`
53
- ----------------
54
- These methods round down to the negative infinity direction.
55
- Its behavior is same as built-in #floor.
56
- ```rb
57
- 1.9.mfloor(1) #=> 1
58
- 1.1.mfloor(1) #=> 1
59
- -1.1.mfloor(1) #=> -2
60
- -1.9.mfloor(1) #=> -2
47
+ | 1.9 1.1 -1.1 -1.9
48
+ -----------------------------------
49
+ .ceil | 2 2 -1 -1 (ruby built-in)
50
+ .floor | 1 1 -2 -2 (ruby built-in)
51
+ .roundup | 2 2 -2 -2
52
+ .rounddown | 1 1 -1 -1
53
+ .round | 2 1 -1 -2 (ruby built-in)
54
+ .truncate | 1 1 -1 -1 (ruby built-in)
55
+ .mceil(1) | 2 2 -1 -1
56
+ .mfloor(1) | 1 1 -2 -2
57
+ .mroundup(1) | 2 2 -2 -2
58
+ .mrounddown(1)| 1 1 -1 -1
59
+ .mround(1) | 2 1 -1 -2
60
+ .mtruncate(1) | 1 1 -1 -1
61
+ .sceil(1) | 2 2 -1 -1
62
+ .sfloor(1) | 1 1 -2 -2
63
+ .sroundup(1) | 2 2 -2 -2
64
+ .srounddown(1)| 1 1 -1 -1
65
+ .sround(1) | 2 1 -1 -2
66
+ .struncate(1) | 1 1 -1 -1
61
67
  ```
62
68
 
63
- `#roundup`, `#mroundup`, `#sroundup`
69
+ Also, try to run `examples/example.rb`
70
+
71
+
72
+ Known Bugs
73
+ ================
74
+ Float presision
64
75
  ----------------
65
- These methods round up to far from 0 direction.
66
76
  ```rb
67
- 1.9.mroundup(1) #=> 2
68
- 1.1.mroundup(1) #=> 2
69
- -1.1.mroundup(1) #=> -2
70
- -1.9.mroundup(1) #=> -2
77
+ 1.2.mrounddown(0.1) #=> 1.1
71
78
  ```
79
+ Oops... Resulting 1.2 is expected.
72
80
 
73
- `#rounddown`, `#mrounddown`, `#srounddown`
74
- ----------------
75
- These methods round down to near from 0 direction.
81
+ Becouse,
76
82
  ```rb
77
- 1.9.mrounddown(1) #=> 1
78
- 1.1.mrounddown(1) #=> 1
79
- -1.1.mrounddown(1) #=> -1
80
- -1.9.mrounddown(1) #=> -1
83
+ 1.2.divmod(0.1) #=> [11, 0.0999999999999999]
81
84
  ```
82
85
 
83
-
84
- `#mround`, `#sround`
85
- ----------------
86
- These methods round off the absolute value, dos not round even.
87
- Its behavior is same as built-in #round.
86
+ To avoid this bug, please use `Rational`.
88
87
  ```rb
89
- 1.9.mround(1) #=> 2
90
- 1.1.mround(1) #=> 1
91
- -1.1.mround(1) #=> -1
92
- -1.9.mround(1) #=> -2
88
+ 1.2r.mrounddown(0.1r) #=> (6/5)
93
89
  ```
94
-
@@ -0,0 +1,19 @@
1
+
2
+ require "pretty_round"
3
+
4
+ xs = [1.9, 1.1, -1.1, -1.9]
5
+
6
+ puts " "*14 + "|" + xs.map{|x| x.to_s.rjust(5)}.join
7
+ puts "-"*(14+1+xs.size*5)
8
+
9
+ %i[ceil floor roundup rounddown round truncate].each do |mthd|
10
+ puts ".#{mthd}".ljust(14)+ "|" + xs.map{|x| x.send(mthd)}.map{|x| x.to_i.to_s.rjust(5)}.join
11
+ end
12
+
13
+ %i[mceil mfloor mroundup mrounddown mround mtruncate].each do |mthd|
14
+ puts ".#{mthd}(1)".ljust(14)+ "|" + xs.map{|x| x.send(mthd,1)}.map{|x| x.to_i.to_s.rjust(5)}.join
15
+ end
16
+
17
+ %i[sceil sfloor sroundup srounddown sround struncate].each do |mthd|
18
+ puts ".#{mthd}(1)".ljust(14)+ "|" + xs.map{|x| x.send(mthd,1)}.map{|x| x.to_i.to_s.rjust(5)}.join
19
+ end
data/lib/pretty_round.rb CHANGED
@@ -26,49 +26,52 @@ class Numeric
26
26
  # Return nearest multiple of given number that is equal to or greater than self.
27
27
  # This method round up to the positive infinity direction.
28
28
  def mceil(num)
29
- #
30
- # MEMO: maybe ruby bug:
31
- # 123.456.divmod(1/10r) => [123456, 4.996003610813204e-16]
32
- #
33
- #div, mod = divmod(num)
34
- div = self.div(num); mod = self - div*num
35
- x = num * div; y = x + (mod.zero? ? 0 : num)
36
- [x, y].max
29
+ if (x = num * div(num)) == self
30
+ self
31
+ else
32
+ [x, x+num].max
33
+ end
37
34
  end
38
35
 
39
36
  # Return nearest multiple of given number that is equal to or less than self.
40
37
  # This method round down to the negative infinity direction.
41
38
  def mfloor(num)
42
- div = self.div(num); mod = self - div*num
43
- x = num * div; y = x + (mod.zero? ? 0 : num)
44
- [x, y].min
39
+ if (x = num * div(num)) == self
40
+ self
41
+ else
42
+ [x, x+num].min
43
+ end
45
44
  end
46
45
 
47
46
  # Return nearest multiple of given number that the absolute is equal to or greater than self.
48
47
  # This method round up to far from 0 direction.
49
48
  def mroundup(num)
50
- div = self.div(num); mod = self - div*num
51
- x = num * div; y = x + (mod.zero? ? 0 : num)
52
- [x, y].max_by(&:abs)
49
+ if (x = num * div(num)) == self
50
+ self
51
+ else
52
+ [x, x+num].max_by(&:abs)
53
+ end
53
54
  end
54
55
 
55
56
  # Return nearest multiple of given number that the absolute is equal to or less than self.
56
57
  # This method round down to near to 0 direction.
57
58
  def mrounddown(num)
58
- div = self.div(num); mod = self - div*num
59
- x = num * div; y = x + (mod.zero? ? 0 : num)
60
- [x, y].min_by(&:abs)
59
+ if (x = num * div(num)) == self
60
+ self
61
+ else
62
+ [x, x+num].min_by(&:abs)
63
+ end
61
64
  end
62
65
 
63
66
  # Retuen nearest multiple of given number.
64
67
  # When self is median of multiple of given number, return the multiple that have greater absolute.
65
68
  def mround(num)
66
- div = self.div(num); mod = self - div*num
67
- x = num * div; y = x + (mod.zero? ? 0 : num)
68
- if mod.quo(num).abs * 2 == 1
69
- [x, y].max_by(&:abs)
69
+ if (x = num * div(num)) == self
70
+ self
71
+ elsif x + x +num == self + self # if self is median
72
+ [x, x+num].max_by(&:abs)
70
73
  else
71
- [x, y].min_by{|t| (t - self).abs}
74
+ [x, x+num].min_by{|t| (t - self).abs}
72
75
  end
73
76
  end
74
77
 
@@ -77,32 +80,32 @@ class Numeric
77
80
 
78
81
  # Ceiling with given significant digit.
79
82
  def sceil(digit)
80
- numdigit = Math.log10(abs).floor + 1
81
- mceil(10**(numdigit - digit))
83
+ selfdigit = Math.log10(abs).floor + 1
84
+ mceil(10**(selfdigit - digit))
82
85
  end
83
86
 
84
87
  # Flooring with given significant digit.
85
88
  def sfloor(digit)
86
- numdigit = Math.log10(abs).floor + 1
87
- mfloor(10**(numdigit - digit))
89
+ selfdigit = Math.log10(abs).floor + 1
90
+ mfloor(10**(selfdigit - digit))
88
91
  end
89
92
 
90
93
  # Rounding up with given significant digit.
91
94
  def sroundup(digit)
92
- numdigit = Math.log10(abs).floor + 1
93
- mroundup(10**(numdigit - digit))
95
+ selfdigit = Math.log10(abs).floor + 1
96
+ mroundup(10**(selfdigit - digit))
94
97
  end
95
98
 
96
99
  # Rounding down with given significant digit.
97
100
  def srounddown(digit)
98
- numdigit = Math.log10(abs).floor + 1
99
- mrounddown(10**(numdigit - digit))
101
+ selfdigit = Math.log10(abs).floor + 1
102
+ mrounddown(10**(selfdigit - digit))
100
103
  end
101
104
 
102
105
  # Rounding off with given significant digit.
103
106
  def sround(digit)
104
- numdigit = Math.log10(abs).floor + 1
105
- mround(10**(numdigit - digit))
107
+ selfdigit = Math.log10(abs).floor + 1
108
+ mround(10**(selfdigit - digit))
106
109
  end
107
110
 
108
111
  alias :struncate :srounddown
@@ -10,8 +10,10 @@ class TEST_PrettyRound < Minitest::Test
10
10
 
11
11
  def test_roundup
12
12
  assert_ep 2, 1.9.roundup
13
+ assert_ep 2, 1.5.roundup
13
14
  assert_ep 2, 1.1.roundup
14
15
  assert_ep -2, -1.1.roundup
16
+ assert_ep -2, -1.5.roundup
15
17
  assert_ep -2, -1.9.roundup
16
18
 
17
19
  x = 123.456
@@ -27,8 +29,10 @@ class TEST_PrettyRound < Minitest::Test
27
29
 
28
30
  def test_rounddown
29
31
  assert_ep 1, 1.9.rounddown
32
+ assert_ep 1, 1.5.rounddown
30
33
  assert_ep 1, 1.1.rounddown
31
34
  assert_ep -1, -1.1.rounddown
35
+ assert_ep -1, -1.5.rounddown
32
36
  assert_ep -1, -1.9.rounddown
33
37
 
34
38
  x = 123.456
@@ -42,10 +46,13 @@ class TEST_PrettyRound < Minitest::Test
42
46
  assert_ep -100, x.rounddown(-2)
43
47
  end
44
48
 
49
+
45
50
  def test_mceil
46
51
  assert_ep 2, 1.9.mceil(1)
52
+ assert_ep 2, 1.5.mceil(1)
47
53
  assert_ep 2, 1.1.mceil(1)
48
54
  assert_ep -1, -1.1.mceil(1)
55
+ assert_ep -1, -1.5.mceil(1)
49
56
  assert_ep -1, -1.9.mceil(1)
50
57
 
51
58
  x = 123.456
@@ -61,8 +68,10 @@ class TEST_PrettyRound < Minitest::Test
61
68
 
62
69
  def test_mfloor
63
70
  assert_ep 1, 1.9.mfloor(1)
71
+ assert_ep 1, 1.5.mfloor(1)
64
72
  assert_ep 1, 1.1.mfloor(1)
65
73
  assert_ep -2, -1.1.mfloor(1)
74
+ assert_ep -2, -1.5.mfloor(1)
66
75
  assert_ep -2, -1.9.mfloor(1)
67
76
 
68
77
  x = 123.456
@@ -78,8 +87,10 @@ class TEST_PrettyRound < Minitest::Test
78
87
 
79
88
  def test_mroundup
80
89
  assert_ep 2, 1.9.mroundup(1)
90
+ assert_ep 2, 1.5.mroundup(1)
81
91
  assert_ep 2, 1.1.mroundup(1)
82
92
  assert_ep -2, -1.1.mroundup(1)
93
+ assert_ep -2, -1.5.mroundup(1)
83
94
  assert_ep -2, -1.9.mroundup(1)
84
95
 
85
96
  x = 123.456
@@ -92,11 +103,13 @@ class TEST_PrettyRound < Minitest::Test
92
103
  assert_ep -123.46, x.mroundup(-0.01)
93
104
  assert_ep -125, x.mroundup(25)
94
105
  end
95
-
106
+
96
107
  def test_mrounddown
97
108
  assert_ep 1, 1.9.mrounddown(1)
109
+ assert_ep 1, 1.5.mrounddown(1)
98
110
  assert_ep 1, 1.1.mrounddown(1)
99
111
  assert_ep -1, -1.1.mrounddown(1)
112
+ assert_ep -1, -1.5.mrounddown(1)
100
113
  assert_ep -1, -1.9.mrounddown(1)
101
114
 
102
115
  x = 123.456
@@ -112,8 +125,10 @@ class TEST_PrettyRound < Minitest::Test
112
125
 
113
126
  def test_mround
114
127
  assert_ep 2, 1.9.mround(1)
128
+ assert_ep 2, 1.5.mround(1)
115
129
  assert_ep 1, 1.1.mround(1)
116
130
  assert_ep -1, -1.1.mround(1)
131
+ assert_ep -2, -1.5.mround(1)
117
132
  assert_ep -2, -1.9.mround(1)
118
133
 
119
134
  x = 123.456
@@ -127,6 +142,25 @@ class TEST_PrettyRound < Minitest::Test
127
142
  assert_ep -125, x.mround(25)
128
143
  end
129
144
 
145
+ def test_mtruncate
146
+ assert_ep 1, 1.9.mtruncate(1)
147
+ assert_ep 1, 1.5.mtruncate(1)
148
+ assert_ep 1, 1.1.mtruncate(1)
149
+ assert_ep -1, -1.1.mtruncate(1)
150
+ assert_ep -1, -1.5.mtruncate(1)
151
+ assert_ep -1, -1.9.mtruncate(1)
152
+
153
+ x = 123.456
154
+ assert_ep 122, x.mtruncate(-2)
155
+ assert_ep 123.45, x.mtruncate(-0.01)
156
+ assert_ep 100, x.mtruncate(25)
157
+
158
+ x = -123.456
159
+ assert_ep -122, x.mtruncate(-2)
160
+ assert_ep -123.45, x.mtruncate(-0.01)
161
+ assert_ep -100, x.mtruncate(25)
162
+ end
163
+
130
164
 
131
165
  def test_sceil
132
166
  x = 123.456
@@ -172,16 +206,12 @@ class TEST_PrettyRound < Minitest::Test
172
206
 
173
207
  def test_srounddown
174
208
  x = 123.456
175
- assert_ep 0, x.srounddown(-1)
176
- assert_ep 0, x.srounddown(0)
177
209
  assert_ep 100, x.srounddown(1)
178
210
  assert_ep 123, x.srounddown(3)
179
211
  assert_ep 123.4, x.srounddown(4)
180
212
  assert_ep 123.456, x.srounddown(6)
181
213
 
182
214
  x = -123.456
183
- assert_ep 0, x.srounddown(-1)
184
- assert_ep 0, x.srounddown(0)
185
215
  assert_ep -100, x.srounddown(1)
186
216
  assert_ep -123, x.srounddown(3)
187
217
  assert_ep -123.4, x.srounddown(4)
@@ -189,6 +219,9 @@ class TEST_PrettyRound < Minitest::Test
189
219
  end
190
220
 
191
221
  def test_sround
222
+ assert_ep 2, 1.5.sround(1)
223
+ assert_ep -2, -1.5.sround(1)
224
+
192
225
  x = 123.456
193
226
  assert_ep 100, x.sround(1)
194
227
  assert_ep 123, x.sround(3)
@@ -201,4 +234,18 @@ class TEST_PrettyRound < Minitest::Test
201
234
  assert_ep -123.5, x.sround(4)
202
235
  assert_ep -123.456, x.sround(6)
203
236
  end
237
+
238
+ def test_struncate
239
+ x = 123.456
240
+ assert_ep 100, x.struncate(1)
241
+ assert_ep 123, x.struncate(3)
242
+ assert_ep 123.4, x.struncate(4)
243
+ assert_ep 123.456, x.struncate(6)
244
+
245
+ x = -123.456
246
+ assert_ep -100, x.struncate(1)
247
+ assert_ep -123, x.struncate(3)
248
+ assert_ep -123.4, x.struncate(4)
249
+ assert_ep -123.456, x.struncate(6)
250
+ end
204
251
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pretty_round
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - diaphragm
@@ -19,6 +19,7 @@ files:
19
19
  - LICENSE
20
20
  - README.md
21
21
  - examples/example.rb
22
+ - examples/example2.rb
22
23
  - lib/pretty_round.rb
23
24
  - test/test_pretty_round.rb
24
25
  homepage: https://github.com/diaphragm/ruby-pretty-round