PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.16.3
GiveWP – Donation Plugin and Fundraising Platform v4.16.3
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 1 year ago Currencies 1 year ago Exception 1 year ago Exchange 1 year ago Formatter 1 year ago PHPUnit 1 year ago Parser 1 year ago Calculator.php 4 years ago Converter.php 1 year ago Currencies.php 1 year ago Currency.php 1 year ago CurrencyPair.php 1 year ago Exception.php 4 years ago Exchange.php 1 year ago Money.php 1 year ago MoneyFactory.php 4 years ago MoneyFormatter.php 1 year ago MoneyParser.php 4 years ago Number.php 1 year ago
Number.php
332 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(sprintf('Invalid integer part %1$s. Invalid digit %2$s found', $number, $digit));
257 }
258
259 if (false === $nonZero && '0' === $digit) {
260 throw new \InvalidArgumentException('Leading zeros are not allowed');
261 }
262
263 $nonZero = true;
264 }
265
266 return $number;
267 }
268
269 /**
270 * @param string $number
271 *
272 * @return string
273 */
274 private static function parseFractionalPart($number)
275 {
276 if ('' === $number) {
277 return $number;
278 }
279
280 for ($position = 0, $characters = strlen($number); $position < $characters; ++$position) {
281 $digit = $number[$position];
282 if (!isset(static::$numbers[$digit])) {
283 throw new \InvalidArgumentException(sprintf('Invalid fractional part %1$s. Invalid digit %2$s found', $number, $digit));
284 }
285 }
286
287 return $number;
288 }
289
290 /**
291 * @param string $moneyValue
292 * @param int $targetDigits
293 * @param int $havingDigits
294 *
295 * @return string
296 */
297 public static function roundMoneyValue($moneyValue, $targetDigits, $havingDigits)
298 {
299 $valueLength = strlen($moneyValue);
300 $shouldRound = $targetDigits < $havingDigits && $valueLength - $havingDigits + $targetDigits > 0;
301
302 if ($shouldRound && $moneyValue[$valueLength - $havingDigits + $targetDigits] >= 5) {
303 $position = $valueLength - $havingDigits + $targetDigits;
304 $addend = 1;
305
306 while ($position > 0) {
307 $newValue = (string) ((int) $moneyValue[$position - 1] + $addend);
308
309 if ($newValue >= 10) {
310 $moneyValue[$position - 1] = $newValue[1];
311 $addend = $newValue[0];
312 --$position;
313 if ($position === 0) {
314 $moneyValue = $addend.$moneyValue;
315 }
316 } else {
317 if ($moneyValue[$position - 1] === '-') {
318 $moneyValue[$position - 1] = $newValue[0];
319 $moneyValue = '-'.$moneyValue;
320 } else {
321 $moneyValue[$position - 1] = $newValue[0];
322 }
323
324 break;
325 }
326 }
327 }
328
329 return $moneyValue;
330 }
331 }
332