GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Pull Request — master (#28)
by t
02:49
created

Numbers::isPrime()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 6
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 11
ccs 0
cts 7
cp 0
crap 20
rs 10
1
<?php
2
/**
3
 * Class Numbers
4
 *
5
 * @link https://www.icy2003.com/
6
 * @author icy2003 <[email protected]>
7
 * @copyright Copyright (c) 2017, icy2003
8
 */
9
namespace icy2003\php\ihelpers;
10
11
use icy2003\php\C;
12
use icy2003\php\I;
13
use icy2003\php\icomponents\excel\Excel;
14
15
/**
16
 * 数字处理
17
 */
18
class Numbers
19
{
20
21
    /**
22
     * 比较两个任意精度的数字
23
     *
24
     * - 修复 bccomp 无法正确比较 0.999999 和 1 的值!!!!
25
     *
26
     * @param string $number1 数字1
27
     * @param string $number2 数字2
28
     * @param integer $scale 精确度,默认精确到小数点后 2 位
29
     *
30
     * @return boolean
31
     */
32 56
    public static function isEquals($number1, $number2, $scale = 2)
33
    {
34 56
        return 0 === bccomp($number1 - $number2, 0, $scale);
35
    }
36
37
    /**
38
     * 加载一些奇怪的常量
39
     *
40
     * 我知道这些符号不好打,所以从注释里复制喽
41
     *
42
     * @constant double π 圆周率
43
     * @constant double e 自然常数
44
     * @constant double γ 欧拉常数
45
     * @constant double φ 黄金比
46
     * @constant double c 光速
47
     *
48
     * @return void
49
     */
50
    public static function load()
51
    {
52
        I::def('π', M_PI);
53
        I::def('e', M_E);
54
        I::def('γ', M_EULER);
55
        I::def('φ', (sqrt(5) - 1) / 2);
56
        I::def('c', 2.99792458e8);
57
    }
58
59
    /**
60
     * 获取数字在指定长度的位置
61
     *
62
     * @param integer $number
63
     * @param integer $length
64
     *
65
     * @return integer
66
     */
67
    public static function position($number, $length)
68
    {
69
        while ($number < 0) {
70
            $number += $length;
71
        }
72
        return $number % $length;
73
    }
74
75
    /**
76
     * 转成字节数
77
     *
78
     * - 支持数字和单位之间有空格
79
     *
80
     * @param string $size 例如:10m、10M、10Tb、10kB 等
81
     *
82
     * @return integer
83
     */
84
    public static function toBytes($size)
85
    {
86
        $callback = function ($matches) {
87
            $sizeMap = [
88
                '' => 0,
89
                'b' => 0, // 为了简化正则
90
                'k' => 1,
91
                'm' => 2,
92
                'g' => 3,
93
                't' => 4,
94
                'p' => 5,
95
            ];
96
97
            return $matches[1] * pow(1024, $sizeMap[strtolower($matches[2])]);
98
        };
99
100
        return (int) preg_replace_callback('/(\d*)\s*([a-z]?)b?/i', $callback, $size, 1);
101
    }
102
103
    /**
104
     * 字节数尽可能转成 k、m、g 等形式
105
     *
106
     * - 支持小单位转大单位
107
     *
108
     * @param integer $bytes
109
     *
110
     * @return string
111
     */
112
    public static function fromBytes($bytes)
113
    {
114
        $bytes = self::toBytes($bytes);
115
        $unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb');
116
        return @round($bytes / pow(1024, ($i = floor(log($bytes, 1024)))), 2) . ' ' . $unit[$i];
117
    }
118
119
    /**
120
     * 比较两个值(如:10m、10M、10Tb、10kB 等)的大小
121
     *
122
     * - 0:相等,-1:左小于右,1:右小于左
123
     *
124
     * @param string $size1
125
     * @param string $size2
126
     *
127
     * @return integer
128
     */
129
    public static function compareSize($size1, $size2)
130
    {
131
        $bytes1 = self::toBytes($size1);
132
        $bytes2 = self::toBytes($size2);
133
        return bccomp($bytes1, $bytes2, 0);
134
    }
135
136
    /**
137
     * 将某进制的字符串转化成另一进制的字符串
138
     *
139
     * @see http://php.net/manual/zh/function.base-convert.php
140
     *
141
     * @param string $numberInput 待转换的字符串
142
     * @param string $fromBaseInput 起始进制的规则
143
     * @param string $toBaseInput 结束进制的规则
144
     *
145
     * @return string
146
     */
147
    public static function baseConvert($numberInput, $fromBaseInput, $toBaseInput)
148
    {
149
        if ($fromBaseInput == $toBaseInput) {
150
            return $numberInput;
151
        }
152
153
        $fromBase = Strings::split($fromBaseInput);
154
        $toBase = Strings::split($toBaseInput);
155
        $number = Strings::split($numberInput);
156
        $fromLen = Strings::length($fromBaseInput);
157
        $toLen = Strings::length($toBaseInput);
158
        $numberLen = Strings::length($numberInput);
159
        $retval = '';
160
        if ($toBaseInput == '0123456789') {
161
            $retval = 0;
162
            for ($i = 1; $i <= $numberLen; $i++) {
163
                $retval = bcadd($retval, bcmul((string) array_search($number[$i - 1], $fromBase), bcpow($fromLen, $numberLen - $i)));
164
            }
165
166
            return $retval;
167
        }
168
        if ($fromBaseInput != '0123456789') {
169
            $base10 = self::baseConvert($numberInput, $fromBaseInput, '0123456789');
170
        } else {
171
            $base10 = $numberInput;
172
        }
173
174
        if ($base10 < Strings::length($toBaseInput)) {
175
            return $toBase[$base10];
176
        }
177
178
        while ($base10 != '0') {
179
            $retval = $toBase[bcmod($base10, $toLen)] . $retval;
180
            $base10 = bcdiv($base10, $toLen, 0);
181
        }
182
        return $retval;
183
    }
184
185
    /**
186
     * 进制转换
187
     *
188
     * - 支持 2、8、10、16 进制之间转换
189
     *
190
     * @param string $number
191
     * @param integer $fromBase 2、8、10、16之间互转
192
     * @param integer $toBase 2、8、10、16之间互转
193
     *
194
     * @return string
195
     */
196
    public static function base($number, $fromBase, $toBase)
197
    {
198
        C::assertTrue(in_array($fromBase, [2, 8, 10, 16]), '原始进制必须为 2、8、10、16 之一');
199
        C::assertTrue(in_array($toBase, [2, 8, 10, 16]), '目标进制必须为 2、8、10、16 之一');
200
        $chars = '0123456789ABCDEF';
201
        return self::baseConvert($number, Strings::sub($chars, 0, $fromBase), Strings::sub($chars, 0, $toBase));
202
    }
203
204
    /**
205
     * 中文大写数字转成小写数字
206
     *
207
     * @param string $number
208
     *
209
     * @return string
210
     */
211
    public static function toLowerChineseCase($number)
212
    {
213
        return Strings::replace($number, [
214
            '零' => '〇',
215
            '壹' => '一',
216
            '贰' => '二',
217
            '叁' => '三',
218
            '肆' => '四',
219
            '伍' => '五',
220
            '陆' => '六',
221
            '柒' => '七',
222
            '捌' => '八',
223
            '玖' => '九',
224
            '拾' => '十',
225
            '佰' => '百',
226
            '仟' => '千',
227
            '圆' => '元',
228
        ]);
229
    }
230
231
    /**
232
     * 中文小写数字转成大写数字
233
     *
234
     * @param string $number
235
     *
236
     * @return string
237
     */
238
    public static function toUpperChineseCase($number)
239
    {
240
        return Strings::replace($number, [
241
            '〇' => '零',
242
            '一' => '壹',
243
            '二' => '贰',
244
            '三' => '叁',
245
            '四' => '肆',
246
            '五' => '伍',
247
            '六' => '陆',
248
            '七' => '柒',
249
            '八' => '捌',
250
            '九' => '玖',
251
            '十' => '拾',
252
            '百' => '佰',
253
            '千' => '仟',
254
            '元' => '圆',
255
        ]);
256
    }
257
258
    /**
259
     * 判断是否为奇数
260
     *
261
     * @param double $number
262
     *
263
     * @return boolean
264
     */
265
    public static function isOdd($number)
266
    {
267
        return $number % 2 === 1;
268
    }
269
270
    /**
271
     * 判断是否为偶数
272
     *
273
     * @param double $number
274
     *
275
     * @return boolean
276
     */
277
    public static function isEven($number)
278
    {
279
        return $number % 2 === 0;
280
    }
281
282
    /**
283
     * 判断是否为质数
284
     *
285
     * @param double $number
286
     *
287
     * @return boolean
288
     */
289
    public static function isPrime($number)
290
    {
291
        if ($number <= 1) {
292
            return false;
293
        }
294
        for ($i = 2; $i <= Excel::sqrt($number); $i++) {
295
            if ($number % $i === 0) {
296
                return false;
297
            }
298
        }
299
        return true;
300
    }
301
}
302