pretty_round 0.1.1 → 0.1.2

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.
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