Passed
Branch master (356932)
by Fabrice
02:58
created

Math::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of OpinHelpers.
5
 *     (c) Fabrice de Stefanis / https://github.com/fab2s/OpinHelpers
6
 * This source file is licensed under the MIT license which you will
7
 * find in the LICENSE file or at https://opensource.org/licenses/MIT
8
 */
9
10
namespace fab2s\OpinHelpers;
11
12
use fab2s\Math\OpinHelpers\MathOpsAbstract;
13
14
/**
15
 * Class Math
16
 */
17
class Math extends MathOpsAbstract
18
{
19
    /**
20
     * Math constructor.
21
     *
22
     * @param string|static $number
23
     *
24
     * @throws \InvalidArgumentException
25
     */
26
    public function __construct($number)
27
    {
28
        if (isset(static::$globalPrecision)) {
29
            $this->precision = static::$globalPrecision;
30
        }
31
32
        $this->number = static::validateInputNumber($number);
33
    }
34
35
    /**
36
     * @return string
37
     */
38
    public function __toString()
39
    {
40
        return static::normalizeNumber($this->number);
41
    }
42
43
    /**
44
     * @param string $number
45
     *
46
     * @throws \InvalidArgumentException
47
     *
48
     * @return static
49
     */
50
    public static function number($number)
51
    {
52
        return new static($number);
53
    }
54
55
    /**
56
     * convert any based value bellow or equals to 64 to its decimal value
57
     *
58
     * @param string $number
59
     * @param int    $base
60
     *
61
     * @throws \InvalidArgumentException
62
     *
63
     * @return static
64
     */
65
    public static function fromBase($number, $base)
66
    {
67
        // trim base 64 padding char, only positive
68
        $number = trim($number, ' =-');
69
        if ($number === '' || strpos($number, '.') !== false) {
70
            throw new \InvalidArgumentException('Argument number is not an integer');
71
        }
72
73
        $baseChar = static::getBaseChar($base);
74
        if (trim($number, $baseChar[0]) === '') {
75
            return new static('0');
76
        }
77
78
        if (static::$gmpSupport && $base <= 62) {
79
            return new static(static::baseConvert($number, $base, 10));
80
        }
81
82
        // By now we know we have a correct base and number
83
        return new static(static::bcDec2Base($number, $base, $baseChar));
84
    }
85
86
    /**
87
     * @param string $number
88
     *
89
     * @throws \InvalidArgumentException
90
     *
91
     * @return bool
92
     */
93
    public function gte($number)
94
    {
95
        return (bool) (bccomp($this->number, static::validateInputNumber($number), $this->precision) >= 0);
96
    }
97
98
    /**
99
     * @param string $number
100
     *
101
     * @throws \InvalidArgumentException
102
     *
103
     * @return bool
104
     */
105
    public function gt($number)
106
    {
107
        return (bool) (bccomp($this->number, static::validateInputNumber($number), $this->precision) === 1);
108
    }
109
110
    /**
111
     * @param string $number
112
     *
113
     * @throws \InvalidArgumentException
114
     *
115
     * @return bool
116
     */
117
    public function lte($number)
118
    {
119
        return (bool) (bccomp($this->number, static::validateInputNumber($number), $this->precision) <= 0);
120
    }
121
122
    /**
123
     * @param string $number
124
     *
125
     * @throws \InvalidArgumentException
126
     *
127
     * @return bool
128
     */
129
    public function lt($number)
130
    {
131
        return (bool) (bccomp($this->number, static::validateInputNumber($number), $this->precision) === -1);
132
    }
133
134
    /**
135
     * @param string $number
136
     *
137
     * @throws \InvalidArgumentException
138
     *
139
     * @return bool
140
     */
141
    public function eq($number)
142
    {
143
        return (bool) (bccomp($this->number, static::validateInputNumber($number), $this->precision) === 0);
144
    }
145
146
    /**
147
     * convert decimal value to any other base bellow or equals to 64
148
     *
149
     * @param int $base
150
     *
151
     * @throws \InvalidArgumentException
152
     *
153
     * @return string
154
     */
155
    public function toBase($base)
156
    {
157
        if ($this->normalize()->hasDecimals()) {
158
            throw new \InvalidArgumentException('Argument number is not an integer in ' . __METHOD__);
159
        }
160
161
        // do not mutate, only support positive integers
162
        $number = ltrim((string) $this, '-');
163
        if (static::$gmpSupport && $base <= 62) {
164
            return static::baseConvert($number, 10, $base);
165
        }
166
167
        $result   = '';
168
        $baseChar = static::getBaseChar($base);
169
        while (bccomp($number, 0) != 0) { // still data to process
170
            $rem    = bcmod($number, $base); // calc the remainder
171
            $number = bcdiv(bcsub($number, $rem), $base);
172
            $result = $baseChar[$rem] . $result;
173
        }
174
175
        $result = $result ? $result : $baseChar[0];
176
177
        return (string) $result;
178
    }
179
180
    /**
181
     * @param int    $decimals
182
     * @param string $decPoint
183
     * @param string $thousandsSep
184
     *
185
     * @return string
186
     */
187
    public function format($decimals = 0, $decPoint = '.', $thousandsSep = ' ')
188
    {
189
        $decimals = max(0, (int) $decimals);
190
        $dec      = '';
191
        // do not mutate
192
        $number   = (new static($this))->round($decimals)->normalize();
193
        $sign     = $number->isPositive() ? '' : '-';
194
        if ($number->abs()->hasDecimals()) {
195
            list($number, $dec) = explode('.', (string) $number);
196
        }
197
198
        if ($decimals) {
199
            $dec = sprintf("%'0-" . $decimals . 's', $dec);
200
        }
201
202
        return $sign . preg_replace("/(?<=\d)(?=(\d{3})+(?!\d))/", $thousandsSep, $number) . ($decimals ? $decPoint . $dec : '');
203
    }
204
}
205
206
// OMG a dynamic static anti pattern ^^
207
Math::gmpSupport();
208