PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 3.19.1
GiveWP – Donation Plugin and Fundraising Platform v3.19.1
4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / vendor / moneyphp / money / src / Number.php
give / vendor / moneyphp / money / src Last commit date
Calculator 4 years ago Currencies 4 years ago Exception 4 years ago Exchange 4 years ago Formatter 4 years ago PHPUnit 4 years ago Parser 4 years ago Calculator.php 4 years ago Converter.php 4 years ago Currencies.php 4 years ago Currency.php 4 years ago CurrencyPair.php 4 years ago Exception.php 4 years ago Exchange.php 4 years ago Money.php 4 years ago MoneyFactory.php 4 years ago MoneyFormatter.php 4 years ago MoneyParser.php 4 years ago Number.php 4 years ago
Number.php
338 lines
1 <?php
2
3 namespace Money;
4
5 /**
6 * Represents a numeric value.
7 *
8 * @author Frederik Bosch <f.bosch@genkgo.nl>
9 */
10 final class Number
11 {
12 /**
13 * @var string
14 */
15 private $integerPart;
16
17 /**
18 * @var string
19 */
20 private $fractionalPart;
21
22 /**
23 * @var array
24 */
25 private static $numbers = [0 => 1, 1 => 1, 2 => 1, 3 => 1, 4 => 1, 5 => 1, 6 => 1, 7 => 1, 8 => 1, 9 => 1];
26
27 /**
28 * @param string $integerPart
29 * @param string $fractionalPart
30 */
31 public function __construct($integerPart, $fractionalPart = '')
32 {
33 if ('' === $integerPart && '' === $fractionalPart) {
34 throw new \InvalidArgumentException('Empty number is invalid');
35 }
36
37 $this->integerPart = $this->parseIntegerPart((string) $integerPart);
38 $this->fractionalPart = $this->parseFractionalPart((string) $fractionalPart);
39 }
40
41 /**
42 * @param $number
43 *
44 * @return self
45 */
46 public static function fromString($number)
47 {
48 $decimalSeparatorPosition = strpos($number, '.');
49 if ($decimalSeparatorPosition === false) {
50 return new self($number, '');
51 }
52
53 return new self(
54 substr($number, 0, $decimalSeparatorPosition),
55 rtrim(substr($number, $decimalSeparatorPosition + 1), '0')
56 );
57 }
58
59 /**
60 * @param float $number
61 *
62 * @return self
63 */
64 public static function fromFloat($number)
65 {
66 if (is_float($number) === false) {
67 throw new \InvalidArgumentException('Floating point value expected');
68 }
69
70 return self::fromString(sprintf('%.14F', $number));
71 }
72
73 /**
74 * @param float|int|string $number
75 *
76 * @return self
77 */
78 public static function fromNumber($number)
79 {
80 if (is_float($number)) {
81 return self::fromString(sprintf('%.14F', $number));
82 }
83
84 if (is_int($number)) {
85 return new self($number);
86 }
87
88 if (is_string($number)) {
89 return self::fromString($number);
90 }
91
92 throw new \InvalidArgumentException('Valid numeric value expected');
93 }
94
95 /**
96 * @return bool
97 */
98 public function isDecimal()
99 {
100 return $this->fractionalPart !== '';
101 }
102
103 /**
104 * @return bool
105 */
106 public function isInteger()
107 {
108 return $this->fractionalPart === '';
109 }
110
111 /**
112 * @return bool
113 */
114 public function isHalf()
115 {
116 return $this->fractionalPart === '5';
117 }
118
119 /**
120 * @return bool
121 */
122 public function isCurrentEven()
123 {
124 $lastIntegerPartNumber = $this->integerPart[strlen($this->integerPart) - 1];
125
126 return $lastIntegerPartNumber % 2 === 0;
127 }
128
129 /**
130 * @return bool
131 */
132 public function isCloserToNext()
133 {
134 if ($this->fractionalPart === '') {
135 return false;
136 }
137
138 return $this->fractionalPart[0] >= 5;
139 }
140
141 /**
142 * @return string
143 */
144 public function __toString()
145 {
146 if ($this->fractionalPart === '') {
147 return $this->integerPart;
148 }
149
150 return $this->integerPart.'.'.$this->fractionalPart;
151 }
152
153 /**
154 * @return bool
155 */
156 public function isNegative()
157 {
158 return $this->integerPart[0] === '-';
159 }
160
161 /**
162 * @return string
163 */
164 public function getIntegerPart()
165 {
166 return $this->integerPart;
167 }
168
169 /**
170 * @return string
171 */
172 public function getFractionalPart()
173 {
174 return $this->fractionalPart;
175 }
176
177 /**
178 * @return string
179 */
180 public function getIntegerRoundingMultiplier()
181 {
182 if ($this->integerPart[0] === '-') {
183 return '-1';
184 }
185
186 return '1';
187 }
188
189 /**
190 * @param int $number
191 *
192 * @return self
193 */
194 public function base10($number)
195 {
196 if (!is_int($number)) {
197 throw new \InvalidArgumentException('Expecting integer');
198 }
199
200 if ($this->integerPart === '0' && !$this->fractionalPart) {
201 return $this;
202 }
203
204 $sign = '';
205 $integerPart = $this->integerPart;
206
207 if ($integerPart[0] === '-') {
208 $sign = '-';
209 $integerPart = substr($integerPart, 1);
210 }
211
212 if ($number >= 0) {
213 $integerPart = ltrim($integerPart, '0');
214 $lengthIntegerPart = strlen($integerPart);
215 $integers = $lengthIntegerPart - min($number, $lengthIntegerPart);
216 $zeroPad = $number - min($number, $lengthIntegerPart);
217
218 return new self(
219 $sign.substr($integerPart, 0, $integers),
220 rtrim(str_pad('', $zeroPad, '0').substr($integerPart, $integers).$this->fractionalPart, '0')
221 );
222 }
223
224 $number = abs($number);
225 $lengthFractionalPart = strlen($this->fractionalPart);
226 $fractions = $lengthFractionalPart - min($number, $lengthFractionalPart);
227 $zeroPad = $number - min($number, $lengthFractionalPart);
228
229 return new self(
230 $sign.ltrim($integerPart.substr($this->fractionalPart, 0, $lengthFractionalPart - $fractions).str_pad('', $zeroPad, '0'), '0'),
231 substr($this->fractionalPart, $lengthFractionalPart - $fractions)
232 );
233 }
234
235 /**
236 * @param string $number
237 *
238 * @return string
239 */
240 private static function parseIntegerPart($number)
241 {
242 if ('' === $number || '0' === $number) {
243 return '0';
244 }
245
246 if ('-' === $number) {
247 return '-0';
248 }
249
250 $nonZero = false;
251
252 for ($position = 0, $characters = strlen($number); $position < $characters; ++$position) {
253 $digit = $number[$position];
254
255 if (!isset(static::$numbers[$digit]) && !(0 === $position && '-' === $digit)) {
256 throw new \InvalidArgumentException(
257 sprintf('Invalid integer part %1$s. Invalid digit %2$s found', $number, $digit)
258 );
259 }
260
261 if (false === $nonZero && '0' === $digit) {
262 throw new \InvalidArgumentException(
263 'Leading zeros are not allowed'
264 );
265 }
266
267 $nonZero = true;
268 }
269
270 return $number;
271 }
272
273 /**
274 * @param string $number
275 *
276 * @return string
277 */
278 private static function parseFractionalPart($number)
279 {
280 if ('' === $number) {
281 return $number;
282 }
283
284 for ($position = 0, $characters = strlen($number); $position < $characters; ++$position) {
285 $digit = $number[$position];
286 if (!isset(static::$numbers[$digit])) {
287 throw new \InvalidArgumentException(
288 sprintf('Invalid fractional part %1$s. Invalid digit %2$s found', $number, $digit)
289 );
290 }
291 }
292
293 return $number;
294 }
295
296 /**
297 * @param string $moneyValue
298 * @param int $targetDigits
299 * @param int $havingDigits
300 *
301 * @return string
302 */
303 public static function roundMoneyValue($moneyValue, $targetDigits, $havingDigits)
304 {
305 $valueLength = strlen($moneyValue);
306 $shouldRound = $targetDigits < $havingDigits && $valueLength - $havingDigits + $targetDigits > 0;
307
308 if ($shouldRound && $moneyValue[$valueLength - $havingDigits + $targetDigits] >= 5) {
309 $position = $valueLength - $havingDigits + $targetDigits;
310 $addend = 1;
311
312 while ($position > 0) {
313 $newValue = (string) ((int) $moneyValue[$position - 1] + $addend);
314
315 if ($newValue >= 10) {
316 $moneyValue[$position - 1] = $newValue[1];
317 $addend = $newValue[0];
318 --$position;
319 if ($position === 0) {
320 $moneyValue = $addend.$moneyValue;
321 }
322 } else {
323 if ($moneyValue[$position - 1] === '-') {
324 $moneyValue[$position - 1] = $newValue[0];
325 $moneyValue = '-'.$moneyValue;
326 } else {
327 $moneyValue[$position - 1] = $newValue[0];
328 }
329
330 break;
331 }
332 }
333 }
334
335 return $moneyValue;
336 }
337 }
338