1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/* |
4
|
|
|
* This file is part of the Cubiche package. |
5
|
|
|
* |
6
|
|
|
* Copyright (c) Cubiche |
7
|
|
|
* |
8
|
|
|
* For the full copyright and license information, please view the LICENSE |
9
|
|
|
* file that was distributed with this source code. |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Cubiche\Domain\System; |
13
|
|
|
|
14
|
|
|
use Cubiche\Core\Comparable\ComparableInterface; |
15
|
|
|
use Cubiche\Domain\Model\NativeValueObject; |
16
|
|
|
|
17
|
|
|
/** |
18
|
|
|
* Abstract Number Class. |
19
|
|
|
* |
20
|
|
|
* @author Karel Osorio Ramírez <[email protected]> |
21
|
|
|
*/ |
22
|
|
|
abstract class Number extends NativeValueObject implements ComparableInterface |
23
|
|
|
{ |
24
|
|
|
/** |
25
|
|
|
* @var float|int|string |
26
|
|
|
*/ |
27
|
|
|
protected $value; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* {@inheritdoc} |
31
|
|
|
*/ |
32
|
|
|
public function toNative() |
33
|
|
|
{ |
34
|
|
|
return $this->value; |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @param RoundingMode $roundingMode |
39
|
|
|
* |
40
|
|
|
* @return \Cubiche\Domain\System\Integer |
41
|
|
|
*/ |
42
|
|
|
abstract public function toInteger(RoundingMode $roundingMode = null); |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @return \Cubiche\Domain\System\Real |
46
|
|
|
*/ |
47
|
|
|
abstract public function toReal(); |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @return Decimal |
51
|
|
|
*/ |
52
|
|
|
abstract public function toDecimal(); |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* @return bool |
56
|
|
|
*/ |
57
|
|
|
abstract public function isInfinite(); |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @return bool |
61
|
|
|
*/ |
62
|
|
|
abstract public function isPositive(); |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @return bool |
66
|
|
|
*/ |
67
|
|
|
abstract public function isNegative(); |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @return bool |
71
|
|
|
*/ |
72
|
|
|
abstract public function isZero(); |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* @param \Cubiche\Domain\System\Number $x |
76
|
|
|
* |
77
|
|
|
* @return \Cubiche\Domain\System\Number |
78
|
|
|
*/ |
79
|
|
|
public function add(Number $x) |
80
|
|
|
{ |
81
|
|
|
return $x->invertedAdd($this); |
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* @param \Cubiche\Domain\System\Number $x |
86
|
|
|
* |
87
|
|
|
* @return \Cubiche\Domain\System\Number |
88
|
|
|
*/ |
89
|
|
|
abstract protected function invertedAdd(Number $x); |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* @param \Cubiche\Domain\System\Integer $x |
93
|
|
|
* |
94
|
|
|
* @return \Cubiche\Domain\System\Number |
95
|
|
|
*/ |
96
|
|
|
abstract public function addInteger(Integer $x); |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* @param \Cubiche\Domain\System\Real $x |
100
|
|
|
* |
101
|
|
|
* @return \Cubiche\Domain\System\Real |
102
|
|
|
*/ |
103
|
|
|
abstract public function addReal(Real $x); |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* @param Decimal $x |
107
|
|
|
* @param int $scale |
108
|
|
|
* |
109
|
|
|
* @return Decimal |
110
|
|
|
*/ |
111
|
|
|
abstract public function addDecimal(Decimal $x, $scale = null); |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* @param \Cubiche\Domain\System\Number $x |
115
|
|
|
* |
116
|
|
|
* @return \Cubiche\Domain\System\Number |
117
|
|
|
*/ |
118
|
|
|
public function sub(Number $x) |
119
|
|
|
{ |
120
|
|
|
return $x->invertedSub($this); |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** |
124
|
|
|
* @param \Cubiche\Domain\System\Number $x |
125
|
|
|
* |
126
|
|
|
* @return \Cubiche\Domain\System\Number |
127
|
|
|
*/ |
128
|
|
|
abstract protected function invertedSub(Number $x); |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* @param \Cubiche\Domain\System\Integer $x |
132
|
|
|
* |
133
|
|
|
* @return \Cubiche\Domain\System\Number |
134
|
|
|
*/ |
135
|
|
|
abstract public function subInteger(Integer $x); |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* @param \Cubiche\Domain\System\Real $x |
139
|
|
|
* |
140
|
|
|
* @return \Cubiche\Domain\System\Real |
141
|
|
|
*/ |
142
|
|
|
abstract public function subReal(Real $x); |
143
|
|
|
|
144
|
|
|
/** |
145
|
|
|
* @param Decimal $x |
146
|
|
|
* |
147
|
|
|
* @return Decimal |
148
|
|
|
*/ |
149
|
|
|
abstract public function subDecimal(Decimal $x); |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* @param \Cubiche\Domain\System\Number $x |
153
|
|
|
* |
154
|
|
|
* @return \Cubiche\Domain\System\Number |
155
|
|
|
*/ |
156
|
|
|
public function mult(Number $x) |
157
|
|
|
{ |
158
|
|
|
return $x->invertedMult($this); |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
/** |
162
|
|
|
* @param \Cubiche\Domain\System\Number $x |
163
|
|
|
* |
164
|
|
|
* @return \Cubiche\Domain\System\Number |
165
|
|
|
*/ |
166
|
|
|
abstract protected function invertedMult(Number $x); |
167
|
|
|
|
168
|
|
|
/** |
169
|
|
|
* @param \Cubiche\Domain\System\Integer $x |
170
|
|
|
* |
171
|
|
|
* @return \Cubiche\Domain\System\Number |
172
|
|
|
*/ |
173
|
|
|
abstract public function multInteger(Integer $x); |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* @param \Cubiche\Domain\System\Real $x |
177
|
|
|
* |
178
|
|
|
* @return \Cubiche\Domain\System\Real |
179
|
|
|
*/ |
180
|
|
|
abstract public function multReal(Real $x); |
181
|
|
|
|
182
|
|
|
/** |
183
|
|
|
* @param Decimal $x |
184
|
|
|
* @param int $scale |
185
|
|
|
* |
186
|
|
|
* @return Decimal |
187
|
|
|
*/ |
188
|
|
|
abstract public function multDecimal(Decimal $x, $scale = null); |
189
|
|
|
|
190
|
|
|
/** |
191
|
|
|
* @param \Cubiche\Domain\System\Number $x |
192
|
|
|
* |
193
|
|
|
* @return \Cubiche\Domain\System\Number |
194
|
|
|
*/ |
195
|
|
|
public function div(Number $x) |
196
|
|
|
{ |
197
|
|
|
return $x->invertedDiv($this); |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
/** |
201
|
|
|
* @param \Cubiche\Domain\System\Number $x |
202
|
|
|
* |
203
|
|
|
* @return \Cubiche\Domain\System\Number |
204
|
|
|
*/ |
205
|
|
|
abstract protected function invertedDiv(Number $x); |
206
|
|
|
|
207
|
|
|
/** |
208
|
|
|
* @param \Cubiche\Domain\System\Number $x |
209
|
|
|
* |
210
|
|
|
* @throws \DomainException |
211
|
|
|
* |
212
|
|
|
* @return static|null |
213
|
|
|
*/ |
214
|
|
View Code Duplication |
protected function divSpecialCases(Number $x) |
|
|
|
|
215
|
|
|
{ |
216
|
|
|
if ($x->isZero()) { |
217
|
|
|
throw new \DomainException('Division by zero is not allowed.'); |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
if (($this->isZero() || $x->isInfinite()) && !$this->isInfinite()) { |
221
|
|
|
return static::fromNative(0); |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
return; |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
/** |
228
|
|
|
* @param \Cubiche\Domain\System\Integer $x |
229
|
|
|
* |
230
|
|
|
* @return \Cubiche\Domain\System\Number |
231
|
|
|
*/ |
232
|
|
|
abstract public function divInteger(Integer $x); |
233
|
|
|
|
234
|
|
|
/** |
235
|
|
|
* @param \Cubiche\Domain\System\Real $x |
236
|
|
|
* |
237
|
|
|
* @return \Cubiche\Domain\System\Real |
238
|
|
|
*/ |
239
|
|
|
abstract public function divReal(Real $x); |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* @param Decimal $x |
243
|
|
|
* @param int $scale |
244
|
|
|
* |
245
|
|
|
* @return Decimal |
246
|
|
|
*/ |
247
|
|
|
abstract public function divDecimal(Decimal $x, $scale = null); |
248
|
|
|
|
249
|
|
|
/** |
250
|
|
|
* @param \Cubiche\Domain\System\Number $x |
251
|
|
|
* |
252
|
|
|
* @return \Cubiche\Domain\System\Number |
253
|
|
|
*/ |
254
|
|
|
public function pow(Number $x) |
255
|
|
|
{ |
256
|
|
|
return $x->invertedPow($this); |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* @param \Cubiche\Domain\System\Number $x |
261
|
|
|
* |
262
|
|
|
* @return \Cubiche\Domain\System\Number |
263
|
|
|
*/ |
264
|
|
|
abstract protected function invertedPow(Number $x); |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* @param \Cubiche\Domain\System\Integer $x |
268
|
|
|
* |
269
|
|
|
* @return \Cubiche\Domain\System\Number |
270
|
|
|
*/ |
271
|
|
|
abstract public function powInteger(Integer $x); |
272
|
|
|
|
273
|
|
|
/** |
274
|
|
|
* @param \Cubiche\Domain\System\Real $x |
275
|
|
|
* |
276
|
|
|
* @return \Cubiche\Domain\System\Real |
277
|
|
|
*/ |
278
|
|
|
abstract public function powReal(Real $x); |
279
|
|
|
|
280
|
|
|
/** |
281
|
|
|
* @param Decimal $x |
282
|
|
|
* @param int $scale |
283
|
|
|
* |
284
|
|
|
* @return Decimal |
285
|
|
|
*/ |
286
|
|
|
abstract public function powDecimal(Decimal $x, $scale = null); |
287
|
|
|
|
288
|
|
|
/** |
289
|
|
|
* @param string $scale |
290
|
|
|
* |
291
|
|
|
* @return \Cubiche\Domain\System\Real |
292
|
|
|
*/ |
293
|
|
|
abstract public function sqrt($scale = null); |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* {@inheritdoc} |
297
|
|
|
*/ |
298
|
|
|
public function compareTo($other) |
299
|
|
|
{ |
300
|
|
|
if (!$other instanceof self) { |
301
|
|
|
throw new \InvalidArgumentException(sprintf( |
302
|
|
|
'Argument "%s" is invalid. Allowed types for argument are "%s".', |
303
|
|
|
$other, |
304
|
|
|
self::class |
305
|
|
|
)); |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
$value = $this->sub($other); |
309
|
|
|
|
310
|
|
|
return $value->isZero() ? 0 : ($value->isPositive() ? 1 : -1); |
311
|
|
|
} |
312
|
|
|
} |
313
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.