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.
Completed
Push — master ( 486f11...b55f68 )
by t
07:38 queued 01:58
created

MathAndTrigonometry   F

Complexity

Total Complexity 138

Size/Duplication

Total Lines 1227
Duplicated Lines 0 %

Test Coverage

Coverage 9%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 232
dl 0
loc 1227
ccs 26
cts 289
cp 0.09
rs 2
c 1
b 0
f 0
wmc 138

76 Methods

Rating   Name   Duplication   Size   Complexity  
A int_i() 0 3 1
A base() 0 7 2
A atan() 0 3 1
A arabic() 0 25 5
A power() 0 3 1
A mmult() 0 16 5
A munit() 0 7 2
A abs() 0 3 1
A factdouble() 0 12 4
A randarray() 0 10 5
A product() 0 4 2
A asin() 0 3 1
A sqrti() 0 3 1
A aggregate() 0 2 1
A tanh() 0 3 1
A coth() 0 3 1
A cosh() 0 3 1
A mdeterm() 0 22 4
A atan2() 0 13 4
A lcm() 0 7 3
B roman() 0 29 8
A multinomial() 0 6 2
A trunc() 0 4 1
A sumx2my2() 0 8 2
A randbetween() 0 3 1
A sumproduct() 0 14 5
A acosh() 0 3 1
A cot() 0 3 1
A exp() 0 3 1
A rand() 0 3 1
A subtotal() 0 2 1
A sequence() 0 10 3
A combina() 0 3 1
A sinh() 0 3 1
A sumx2py2() 0 8 2
A rounddown() 0 4 2
A seriessum() 0 8 2
A roundup() 0 4 2
A even() 0 7 2
A sqrt() 0 3 1
A sumxmy2() 0 8 2
A mround() 0 3 1
A acot() 0 3 1
A radians() 0 3 1
A csch() 0 3 1
A csc() 0 3 1
A round() 0 3 1
A pi() 0 3 1
A quotient() 0 3 1
A atanh() 0 3 1
A sumsq() 0 6 2
A sec() 0 3 1
A combin() 0 3 1
A acos() 0 3 1
A sumif() 0 3 1
A mod() 0 3 1
A decimal() 0 3 1
A log() 0 3 1
A sech() 0 3 1
A sumifs() 0 3 1
A degrees() 0 3 1
A ln() 0 3 1
A fact() 0 11 3
A log10() 0 3 1
B gcd() 0 20 7
A ceiling() 0 3 2
A cos() 0 3 1
A sin() 0 3 1
A asinh() 0 3 1
A sum() 0 4 2
A floor() 0 3 3
A tan() 0 3 1
A acoth() 0 3 1
A sign() 0 3 2
A odd() 0 7 2
A minverse() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like MathAndTrigonometry often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use MathAndTrigonometry, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Trait MathAndTrigonometry
4
 *
5
 * @link https://www.icy2003.com/
6
 * @author icy2003 <[email protected]>
7
 * @copyright Copyright (c) 2017, icy2003
8
 */
9
10
namespace icy2003\php\icomponents\excel;
11
12
use icy2003\php\ihelpers\Arrays;
13
use icy2003\php\ihelpers\Strings;
14
15
/**
16
 * 数学和三角
17
 */
18
trait MathAndTrigonometry
19
{
20
    /**
21
     * 返回数字的绝对值
22
     *
23
     * - y = |x|, x ∈ (-∞, +∞)
24
     *
25
     * @param double  $number 必需。 需要计算其绝对值的实数
26
     *
27
     * @return double
28
     */
29 1
    public static function abs($number)
30
    {
31 1
        return abs($number);
32
    }
33
34
    /**
35
     * 返回数字的反余弦值
36
     *
37
     * - y = arccos(x), x ∈ [-1, 1]
38
     *
39
     * @param double $number 必需。 所求角度的余弦值,必须介于 -1 到 1 之间
40
     *
41
     * @return double
42
     */
43 1
    public static function acos($number)
44
    {
45 1
        return acos($number);
46
    }
47
48
    /**
49
     * 返回数字的反双曲余弦值
50
     *
51
     * - y = arcosh(x) = ln(x + √(x^2 -1)), x ∈ [1, +∞)
52
     *
53
     * @param double $number 必需。 大于或等于 1 的任意实数
54
     *
55
     * @return double
56
     */
57 1
    public static function acosh($number)
58
    {
59 1
        return acosh($number);
60
    }
61
62
    /**
63
     * 返回数字的反余切值的主值
64
     *
65
     * - y = arccot(x), x ∈ (-∞, +∞)
66
     *
67
     * @param double $number 必需。 Number 为所需角度的余切值。 此值必须是实数
68
     *
69
     * @return double
70
     */
71 1
    public static function acot($number)
72
    {
73 1
        return pi() / 2 - atan($number);
74
    }
75
76
    /**
77
     * 返回数字的反双曲余切值
78
     *
79
     * - y = arccoth(x) = arctanh(1 / x), {x| x > 1 或 x < -1}
80
     *
81
     * @param double $number 必需。 Number 的绝对值必须大于 1
82
     *
83
     * @return double
84
     */
85 1
    public static function acoth($number)
86
    {
87 1
        return atanh(1 / $number);
88
    }
89
90
    /**
91
     * 【数学和三角】返回列表或数据库中的合计。 AGGREGATE 函数可将不同的聚合函数应用于列表或数据库,并提供忽略隐藏行和错误值的选项。
92
     *
93
     * @todo
94
     *
95
     * @return void
96
     */
97
    public static function aggregate()
98
    {
99
100
    }
101
102
    /**
103
     * 将罗马数字转换为阿拉伯数字
104
     *
105
     * @param string $string 必需。 用引号引起的字符串、空字符串 ("") 或对包含文本的单元格的引用
106
     *
107
     * @return integer
108
     */
109 1
    public static function arabic($string)
110
    {
111
        $roman = array(
112 1
            'M' => 1000,
113
            'D' => 500,
114
            'C' => 100,
115
            'L' => 50,
116
            'X' => 10,
117
            'V' => 5,
118
            'I' => 1,
119
        );
120 1
        $strlen = Strings::length($string);
121 1
        $values = [];
122 1
        for ($i = 0; $i < $strlen; $i++) {
123 1
            if (isset($roman[strtoupper($string[$i])])) {
124 1
                $values[] = $roman[strtoupper($string[$i])];
125
            }
126
        }
127
128 1
        $sum = 0;
129 1
        while ($current = current($values)) {
130 1
            $next = next($values);
131 1
            $next > $current ? $sum += $next - $current + 0 * next($values) : $sum += $current;
132
        }
133 1
        return $sum;
134
    }
135
136
    /**
137
     * 返回数字的反正弦值
138
     *
139
     * - y = arcsin(x), x ∈ [-1, 1]
140
     *
141
     * @param double $number 必需。 所求角度的正弦值,必须介于 -1 到 1 之间
142
     *
143
     * @return double
144
     */
145 1
    public static function asin($number)
146
    {
147 1
        return asin($number);
148
    }
149
150
    /**
151
     * 返回数字的反双曲正弦值
152
     *
153
     * - y = arsinh(x) = ln(x + √(x^2 + 1)), x ∈ (-∞, +∞)
154
     *
155
     * @param double $number 必需。 任意实数
156
     *
157
     * @return double
158
     */
159 1
    public static function asinh($number)
160
    {
161 1
        return asinh($number);
162
    }
163
164
    /**
165
     * 返回数字的反正切值
166
     *
167
     * - y = arctan(x), x ∈(-π/2, π/2)
168
     *
169
     * @param double $number 必需。 所求角度的正切值
170
     *
171
     * @return double
172
     */
173
    public static function atan($number)
174
    {
175
        return atan($number);
176
    }
177
178
    /**
179
     * 返回给定的 X 轴及 Y 轴坐标值的反正切值
180
     *
181
     * @param double $x 必需。 点的 x 坐标
182
     * @param double $y 必需。 点的 y 坐标
183
     *
184
     * @return double
185
     */
186
    public static function atan2($x, $y)
187
    {
188
        $pi = 0;
189
        $sign = 1;
190
        if ($y < 0) {
191
            $sign = -1;
192
        }
193
        if ($x < 0) {
194
            $pi = pi();
195
        } elseif ($x == 0) {
196
            return pi() / 2 * $sign;
197
        }
198
        return $pi + $sign * self::atan(self::abs($y / $x));
199
    }
200
201
    /**
202
     * 返回数字的反双曲正切值
203
     *
204
     * - y = artanh(x), x ∈(-1, 1) = 1/2 * ln((1 + x) / (1 - x))
205
     *
206
     * @param double $number 必需。 -1 到 1 之间的任意实数
207
     *
208
     * @return double
209
     */
210
    public static function atanh($number)
211
    {
212
        return atanh($number);
213
    }
214
215
    /**
216
     * 将数字转换为具备给定基数的文本表示
217
     *
218
     * @param string $number 必需。 要转换的数字。 必须是大于或等于0且小于 2 ^ 53 的整数
219
     * @param integer $base 必需。 要将数字转换为的基础基数。 必须是大于或等于2且小于或等于36的整数
220
     * @param integer $minLength 可选。 返回的字符串的最小长度。 必须是大于或等于0的整数
221
     *
222
     * @return string
223
     */
224
    public static function base($number, $base, $minLength = null)
225
    {
226
        $string = base_convert($number, 10, $base);
227
        if (null === $minLength) {
228
            return $string;
229
        } else {
230
            return str_pad($string, $minLength, STR_PAD_LEFT);
231
        }
232
    }
233
234
    /**
235
     * 返回将参数 number 向上舍入(沿绝对值增大的方向)为最接近的指定基数的倍数
236
     *
237
     * @param double $number  必需。 要舍入的值
238
     * @param double $significance 必需。 要舍入到的倍数
239
     *
240
     * @return double
241
     */
242
    public static function ceiling($number, $significance = 1)
243
    {
244
        return is_numeric($number) ? (ceil($number / $significance) * $significance) : false;
0 ignored issues
show
introduced by
The condition is_numeric($number) is always true.
Loading history...
245
    }
246
247
    /**
248
     * 返回给定数目的项目的组合数
249
     *
250
     * - C(m,n) = n! / (m! * (n - m)!),其中 0 ≤ m ≤ n
251
     *
252
     * @param integer $n 必需。 项目的数量
253
     * @param integer $m 必需。 每一组合中项目的数量
254
     *
255
     * @return integer
256
     */
257
    public static function combin($n, $m)
258
    {
259
        return (self::fact($n) / (self::fact($m) * self::fact($n - $m)));
260
    }
261
262
    /**
263
     * 返回给定数目的项的组合数(包含重复)
264
     *
265
     * @param integer $n 必需。 必须大于或等于 0 并大于或等于 m 非整数值将被截尾取整
266
     * @param integer $m 必需。 必须大于或等于 0。 非整数值将被截尾取整
267
     *
268
     * @return integer
269
     */
270
    public static function combina($n, $m)
271
    {
272
        return self::combin($n + $m - 1, $n - 1);
273
    }
274
275
    /**
276
     * 返回已知角度的余弦值
277
     *
278
     * @param double $number 必需。 想要求余弦的角度,以弧度表示
279
     *
280
     * @return double
281
     */
282
    public static function cos($number)
283
    {
284
        return cos($number);
285
    }
286
287
    /**
288
     * 返回数字的双曲余弦值
289
     *
290
     * - y = cosh(x) = (e^x + e^(-x)) / 2
291
     *
292
     * @param double $number 必需。 想要求双曲余弦的任意实数
293
     *
294
     * @return double
295
     */
296
    public static function cosh($number)
297
    {
298
        return cosh($number);
299
    }
300
301
    /**
302
     * 返回以弧度表示的角度的余切值
303
     *
304
     * @param double $number 必需。 要获得其余切值的角度,以弧度表示
305
     *
306
     * @return double
307
     */
308
    public static function cot($number)
309
    {
310
        return -tan(pi() / 2 + $number);
311
    }
312
313
    /**
314
     * 返回一个双曲角度的双曲余切值
315
     *
316
     * - y = coth(x) = 1 / tanh(x) = (e^x + e^(-x)) / (e^x - e^(-x))
317
     *
318
     * @param double $number 必需
319
     *
320
     * @return double
321
     */
322
    public static function coth($number)
323
    {
324
        return 1 / tanh($number);
325
    }
326
327
    /**
328
     * 返回角度的余割值,以弧度表示
329
     *
330
     * @param double $number 必需
331
     *
332
     * @return double
333
     */
334
    public static function csc($number)
335
    {
336
        return 1 / sin($number);
337
    }
338
339
    /**
340
     * 返回角度的双曲余割值,以弧度表示
341
     *
342
     * - y = csch(x) = 1 / sinh(x) = 2 / (e^x - e^(-x))
343
     *
344
     * @param double $number 必需
345
     *
346
     * @return double
347
     */
348
    public static function csch($number)
349
    {
350
        return 1 / sinh($number);
351
    }
352
353
    /**
354
     * 按给定基数将数字的文本表示形式转换成十进制数
355
     *
356
     * @param string $text 必需
357
     * @param integer $radix 必需。Radix 必须是整数
358
     *
359
     * @return string
360
     */
361
    public static function decimal($text, $radix)
362
    {
363
        return base_convert($text, $radix, 10);
364
    }
365
366
    /**
367
     * 将弧度转换为度
368
     *
369
     * @param double $angle
370
     *
371
     * @return double
372
     */
373
    public static function degrees($angle)
374
    {
375
        return rad2deg($angle);
376
    }
377
378
    /**
379
     * 返回数字向上舍入到的最接近的偶数
380
     *
381
     * @param double $number 必需。 要舍入的值
382
     *
383
     * @return integer
384
     */
385
    public static function even($number)
386
    {
387
        $number = ceil($number);
388
        if ($number % 2 == 1) {
389
            $number += 1;
390
        }
391
        return (int) $number;
392
    }
393
394
    /**
395
     * 返回 e 的 n 次幂。 常数 e 等于 2.71828182845904,是自然对数的底数
396
     *
397
     * @param integer $number
398
     *
399
     * @return double
400
     */
401
    public static function exp($number)
402
    {
403
        return exp($number);
404
    }
405
406
    /**
407
     * 返回数的阶乘
408
     *
409
     * @param integer|double $number 必需。 要计算其阶乘的非负数。 如果 number 不是整数,将被截尾取整
410
     *
411
     * @return integer
412
     */
413
    public static function fact($number)
414
    {
415
        $number = (int) floor($number);
416
        if ($number == 0) {
417
            return 1;
418
        }
419
        $result = 1;
420
        foreach (Arrays::rangeGenerator(1, $number) as $num) {
421
            $result *= $num;
422
        }
423
        return $result;
424
    }
425
426
    /**
427
     * 返回数字的双倍阶乘
428
     *
429
     * - 偶数:n!! = n * (n - 2) * (n - 4) * ... * 4 * 2
430
     * - 奇数:n!! = n * (n - 2) * (n - 4) * ... * 3 * 1
431
     *
432
     * @param integer $number 必需。 为其返回双倍阶乘的值。 如果 number 不是整数,将被截尾取整
433
     *
434
     * @return integer
435
     */
436
    public static function factdouble($number)
437
    {
438
        $number = floor($number);
439
        if ($number == 0) {
440
            return 1;
441
        }
442
        $result = 1;
443
        $isEven = $number % 2 == 0;
444
        foreach (Arrays::rangeGenerator($isEven ? 2 : 1, $number, 2) as $num) {
0 ignored issues
show
Bug introduced by
$number of type double is incompatible with the type integer expected by parameter $end of icy2003\php\ihelpers\Arrays::rangeGenerator(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

444
        foreach (Arrays::rangeGenerator($isEven ? 2 : 1, /** @scrutinizer ignore-type */ $number, 2) as $num) {
Loading history...
445
            $result *= $num;
446
        }
447
        return $result;
448
    }
449
450
    /**
451
     * 将参数 number 向下舍入(沿绝对值减小的方向)为最接近的 significance 的倍数
452
     *
453
     * @param double $number 必需。 要舍入的数值
454
     * @param double $significance 必需。 要舍入到的倍数
455
     *
456
     * @return double
457
     */
458
    public static function floor($number, $significance = 1)
459
    {
460
        return (is_numeric($number) && is_numeric($significance)) ? (floor($number / $significance) * $significance) : false;
0 ignored issues
show
introduced by
The condition is_numeric($significance) is always true.
Loading history...
461
    }
462
463
    /**
464
     * 返回两个或多个整数的最大公约数。 最大公约数是能够同时整除 number1 和 number2 而没有余数的最大整数
465
     *
466
     * @param integer|array $number1 Number1 是必需的,后续数字是可选的。 介于 1 和 255 之间的值
467
     *
468
     * @return integer
469
     */
470
    public static function gcd($number1)
471
    {
472
        $numbers = is_array($number1) ? $number1 : func_get_args();
473
        $n = min($numbers);
474
        if (in_array(0, $numbers)) {
475
            return max($numbers);
476
        }
477
        for ($i = $n; $i > 1; $i--) {
478
            $isFind = true;
479
            foreach ($numbers as $num) {
480
                if (false === is_int($num / $i)) {
481
                    $isFind = false;
482
                    break;
483
                }
484
            }
485
            if (true === $isFind) {
486
                return $i;
487
            }
488
        }
489
        return 1;
490
    }
491
492
    /**
493
     * 将数字向下舍入到最接近的整数
494
     *
495
     * - int 是关键字,这里用上后缀 _i
496
     *
497
     * @param double $number 必需。 需要进行向下舍入取整的实数
498
     *
499
     * @return integer
500
     */
501
    public static function int_i($number)
502
    {
503
        return floor($number);
504
    }
505
506
    /**
507
     * 返回整数的最小公倍数。 最小公倍数是所有整数参数 number1、number2 等的倍数中的最小正整数。 使用 LCM 添加具有不同分母的分数
508
     *
509
     * @param integer|array $number1 Number1 是必需的,后续数字是可选的。 要计算其最小公倍数的 1 到 255 个值
510
     *
511
     * @return integer
512
     */
513
    public static function lcm($number1)
514
    {
515
        $numbers = is_array($number1) ? $number1 : func_get_args();
516
        if (in_array(0, $numbers)) {
517
            return 0;
518
        }
519
        return array_product($numbers) / self::gcd($numbers);
520
    }
521
522
    /**
523
     * 返回数字的自然对数。 自然对数以常数 e (2.71828182845904) 为底
524
     *
525
     * @param double $number 必需。 想要计算其自然对数的正实数
526
     *
527
     * @return double
528
     */
529
    public static function ln($number)
530
    {
531
        return log($number);
532
    }
533
534
    /**
535
     * 根据指定底数返回数字的对数
536
     *
537
     * - 注意:此和 PHP 的 log 的默认底不一样,PHP 的默认底是自然对数 e
538
     *
539
     * @param double $number 必需。 想要计算其对数的正实数
540
     * @param double $base 可选。 对数的底数。 如果省略 base,则假定其值为 10
541
     *
542
     * @return double
543
     */
544
    public static function log($number, $base = 10)
545
    {
546
        return log($number, $base);
547
    }
548
549
    /**
550
     * 返回数字以 10 为底的对数
551
     *
552
     * @param double $number 必需。 想要计算其以 10 为底的对数的正实数
553
     *
554
     * @return double
555
     */
556
    public static function log10($number)
557
    {
558
        return log($number, 10);
559
    }
560
561
    /**
562
     * 返回一个数组的矩阵行列式的值
563
     *
564
     * - det(A) = ai1Ai1 + ... + ainAin
565
     *
566
     * @param array $array 必需。 行数和列数相等的数值数组
567
     *
568
     * @return double
569
     */
570
    public static function mdeterm($array)
571
    {
572
        $n = count($array);
573
        $sum = 0;
574
        $prod = 1;
575
        for ($i = 0; $i < $n; $i++) {
576
            for ($j = 0; $j < $n; $j++) {
577
                $x = ($j + $i) % $n;
578
                $y = $j % $n;
579
                $prod *= $array[$x][$y];
580
            }
581
            $sum += $prod;
582
            $prod = 1;
583
            for ($j = $n - 1; $j >= 0; $j--) {
584
                $x = ($j + $i) % $n;
585
                $y = ($n - $j) % $n;
586
                $prod *= $array[$x][$y];
587
            }
588
            $sum -= $prod;
589
            $prod = 1;
590
        }
591
        return $sum;
592
    }
593
594
    /**
595
     * 返回数组中存储的矩阵的逆矩阵
596
     *
597
     * @todo
598
     *
599
     * @return array
600
     */
601
    public static function minverse()
602
    {
603
        return [];
604
    }
605
606
    /**
607
     * 返回两个数组的矩阵乘积。 结果矩阵的行数与 array1 的行数相同,矩阵的列数与 array2 的列数相同
608
     *
609
     * - Aij = ∑(k = 1, n)Bik * Ckj,其中 i 为行数,j 为列数
610
     * - 矩阵乘积物理含义:
611
     *
612
     * | 买家\产品 | A | B | C |
613
     * | - | - | - | - |
614
     * | 甲 | 3 个 | 4 个 | 1 个 |
615
     * | 乙 | 4 个 | 1 个 | 2 个 |
616
     *
617
     * | 产品 | 价格 | 重量 |
618
     * | - | - | - |
619
     * | A | 5 元 | 10 斤 |
620
     * | B | 10 元 | 5 斤 |
621
     * | C | 9 元 | 6 斤 |
622
     *
623
     * | 买家 | 总花费 | 总重量 |
624
     * | - | - | - |
625
     * | 甲 | 64 | 56 |
626
     * | 乙 | 48 | 57 |
627
     *
628
     * @param array $array1
629
     * @param array $array2
630
     *
631
     * @return array|false
632
     */
633
    public static function mmult($array1, $array2)
634
    {
635
        list($col1, $row1) = Arrays::colRowCount($array1);
636
        list($col2, $row2) = Arrays::colRowCount($array2);
637
        if ($col1 === $row2 && $row1 === $col2) {
638
            $arr = [];
639
            for ($r = 0; $r < $row1; $r++) {
640
                for ($c = 0; $c < $col2; $c++) {
641
                    $arr[$r][$c] = array_sum(array_map(function ($a1, $a2) {
642
                        return $a1 * $a2;
643
                    }, $array1[$r], Arrays::column($array2, $c)));
644
                }
645
            }
646
            return $arr;
647
        } else {
648
            return false;
649
        }
650
    }
651
652
    /**
653
     * 返回两数相除的余数
654
     *
655
     * @param integer $number 必需。 要计算余数的被除数
656
     * @param integer $divisor 必需。 除数
657
     *
658
     * @return integer
659
     */
660
    public static function mod($number, $divisor)
661
    {
662
        return $number % $divisor;
663
    }
664
665
    /**
666
     * 返回舍入到所需倍数的数字
667
     *
668
     * - 相比 Excel 的函数,此函数在符号不同时也能返回
669
     *
670
     * @param double $number 必需。 要舍入的值
671
     * @param double $multiple 必需。 要舍入到的倍数
672
     *
673
     * @return double
674
     */
675
    public static function mround($number, $multiple)
676
    {
677
        return round($number / $multiple) * $multiple;
678
    }
679
680
    /**
681
     * 返回参数和的阶乘与各参数阶乘乘积的比值
682
     *
683
     * @param double $number1 Number1 是必需的,后续数字是可选的
684
     *
685
     * @return void
686
     */
687
    public static function multinomial($number1)
688
    {
689
        $numbers = is_array($number1) ? $number1 : func_get_args();
690
        return self::fact(array_sum($numbers)) / array_product(array_map(function ($num) {
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::fact(array_.../* ... */ }, $numbers)) returns the type double which is incompatible with the documented return type void.
Loading history...
691
            return self::fact($num);
692
        }, $numbers));
693
    }
694
695
    /**
696
     * 返回指定维度的单位矩阵
697
     *
698
     * - 1NxN =
699
     * ```
700
     * 1 0 ... 0
701
     * 0 1 ... 0
702
     * ...   ...
703
     * 0 0 ... 1
704
     * ```
705
     * - 注:null 值在 php 里做运算时被看成 0,因此无需对 0 的元素进行赋值
706
     *
707
     * @param integer $dimension 必需。 Dimension 是一个整数, 指定要返回的单位矩阵的维度。 它返回一个数组。 维度必须大于零
708
     *
709
     * @return array
710
     */
711
    public static function munit($dimension)
712
    {
713
        $array = [];
714
        for ($i = 0; $i < $dimension; $i++) {
715
            $array[$i][$i] = 1;
716
        }
717
        return $array;
718
    }
719
720
    /**
721
     * 返回数字向上舍入到的最接近的奇数
722
     *
723
     * @param double $number 必需。 要舍入的值
724
     *
725
     * @return integer
726
     */
727
    public static function odd($number)
728
    {
729
        $number = ceil($number);
730
        if ($number % 2 == 0) {
731
            $number += 1;
732
        }
733
        return (int) $number;
734
    }
735
736
    /**
737
     * 数学常量 pi
738
     *
739
     * @return double
740
     */
741
    public static function pi()
742
    {
743
        return pi();
744
    }
745
746
    /**
747
     * 返回数字乘幂的结果
748
     *
749
     * @param double $number  必需。 基数。 可为任意实数
750
     * @param double $power 必需。 基数乘幂运算的指数
751
     *
752
     * @return double
753
     */
754
    public static function power($number, $power)
755
    {
756
        return pow($number, $power);
757
    }
758
759
    /**
760
     * PRODUCT函数将以参数形式给出的所有数字相乘
761
     *
762
     * @param double $number1 必需。 要相乘的第一个数字或范围
763
     *
764
     * @return double
765
     */
766
    public static function product($number1)
767
    {
768
        $numbers = is_array($number1) ? $number1 : func_get_args();
769
        return array_product($numbers);
770
    }
771
772
    /**
773
     * 返回除法的整数部分。 要放弃除法的余数时,可使用此函数
774
     *
775
     * @param double $numberator 必需。 被除数
776
     * @param double $denominator 必需。 除数
777
     *
778
     * @return integer
779
     */
780
    public static function quotient($numberator, $denominator)
781
    {
782
        return (int) ($numberator / $denominator);
783
    }
784
785
    /**
786
     * 将度数转换为弧度
787
     *
788
     * @param double $angle 必需。 要转换的以度数表示的角度
789
     *
790
     * @return double
791
     */
792
    public static function radians($angle)
793
    {
794
        return deg2rad($angle);
795
    }
796
797
    /**
798
     * 返回了一个大于等于 0 且小于 1 的平均分布的随机实数
799
     *
800
     * @return double
801
     */
802
    public static function rand()
803
    {
804
        return mt_rand(0, (int) self::power(10, 10)) / self::power(10, 10);
805
    }
806
807
    /**
808
     * 函数返回一组随机数字。 可指定要填充的行数和列数,最小值和最大值,以及是否返回整数或小数值
809
     *
810
     * @param integer $row 要返回的行数
811
     * @param integer $col 要返回的列数
812
     * @param integer $min 想返回的最小数值
813
     * @param integer $max 想返回的最大数值
814
     * @param boolean $isInt 返回整数或小数
815
     *
816
     * @return array
817
     */
818
    public static function randarray($row = 1, $col = 1, $min = 0, $max = null, $isInt = false)
819
    {
820
        null === $max && $max = (int) pow(10, 10);
821
        $array = [];
822
        for ($i = 0; $i < $row; $i++) {
823
            for ($j = 0; $j < $col; $j++) {
824
                $array[$i][$j] = mt_rand($min, $max) + ($isInt ? 0 : mt_rand(0, (int) pow(10, 10)) / pow(10, 10));
825
            }
826
        }
827
        return $array;
828
    }
829
830
    /**
831
     * 返回位于两个指定数之间的一个随机整数
832
     *
833
     * @param integer $bottom 必需。 RANDBETWEEN 将返回的最小整数
834
     * @param integer $top 必需。 RANDBETWEEN 将返回的最大整数
835
     *
836
     * @return integer
837
     */
838
    public static function randbetween($bottom, $top)
839
    {
840
        return mt_rand($bottom, $top);
841
    }
842
843
    /**
844
     * 将阿拉伯数字转换为文字形式的罗马数字
845
     *
846
     * - 注意:不支持简明版
847
     *
848
     * @param integer $number
849
     *
850
     * @return string|false
851
     */
852
    public static function roman($number)
853
    {
854
        if (!is_numeric($number) || $number > 3999 || $number <= 0) {
0 ignored issues
show
introduced by
The condition is_numeric($number) is always true.
Loading history...
855
            return false;
856
        }
857
858
        $roman = array(
859
            'M' => 1000,
860
            'D' => 500,
861
            'C' => 100,
862
            'L' => 50,
863
            'X' => 10,
864
            'V' => 5,
865
            'I' => 1,
866
        );
867
        foreach ($roman as $k => $v) {
868
            if (($amount[$k] = floor($number / $v)) > 0) {
869
                $number -= $amount[$k] * $v;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $amount seems to be defined later in this foreach loop on line 868. Are you sure it is defined here?
Loading history...
870
            }
871
        }
872
873
        // Build the string:
874
        $return = '';
875
        $oldK = '';
876
        foreach ($amount as $k => $v) {
877
            $return .= $v <= 3 ? str_repeat($k, $v) : $k . $oldK;
878
            $oldK = $k;
879
        }
880
        return str_replace(array('VIV', 'LXL', 'DCD'), array('IX', 'XC', 'CM'), $return);
881
    }
882
883
    /**
884
     * 函数将数字四舍五入到指定的位数
885
     *
886
     * @param double $number 必需。 要四舍五入的数字
887
     * @param integer $digits 要进行四舍五入运算的位数
888
     *
889
     * @return double
890
     */
891
    public static function round($number, $digits = 0)
892
    {
893
        return round($number, $digits);
894
    }
895
896
    /**
897
     * 朝着零的方向将数字进行向下舍入
898
     *
899
     * @param double $number 必需。需要向下舍入的任意实数
900
     * @param integer $digits 要将数字舍入到的位数
901
     *
902
     * @return double
903
     */
904
    public static function rounddown($number, $digits = 0)
905
    {
906
        $sign = $number >= 0 ? 1 : -1;
907
        return round(abs($number) - 0.5 * pow(10, -$digits), $digits) * $sign;
908
    }
909
910
    /**
911
     * 朝着远离 0(零)的方向将数字进行向上舍入
912
     *
913
     * @param double $number 必需。需要向下舍入的任意实数
914
     * @param integer $digits 要将数字舍入到的位数
915
     *
916
     * @return double
917
     */
918
    public static function roundup($number, $digits = 0)
919
    {
920
        $sign = $number >= 0 ? 1 : -1;
921
        return round(abs($number) + 0.5 * pow(10, -$digits), $digits) * $sign;
922
    }
923
924
    /**
925
     * 返回角度的正割值
926
     *
927
     * - 定义:sec(x) = 1 / cos(x),{ x | x ≠ k*π + π/2,k ∈ Z }
928
     *
929
     * @param double $number 必需。 Number 为需要对其进行正割的角度 (以弧度为单位)
930
     *
931
     * @return double
932
     */
933
    public static function sec($number)
934
    {
935
        return 1 / cos($number);
936
    }
937
938
    /**
939
     * 返回角度的双曲正割值
940
     *
941
     * - y = sech(x) = 1 / cosh(x) = 2 / (e^x + e^(-x))
942
     *
943
     * @param double $number 必需。 Number 为对应所需双曲正割值的角度,以弧度表示
944
     *
945
     * @return double
946
     */
947
    public static function sech($number)
948
    {
949
        return 1 / self::cosh($number);
950
    }
951
952
    /**
953
     * 返回基于以下公式的幂级数之和
954
     *
955
     * - Series(x, n, m, a) = a1 * x^n + a2 * x^(n + m) + a3 * x^(n + 2*m) + ... + ai * x^(n + (i - 1)*m)
956
     *
957
     * @param double $x 必需。 幂级数的输入值
958
     * @param double $n 必需。 x 的首项乘幂
959
     * @param double $m 必需。 级数中每一项的乘幂 n 的步长增加值
960
     * @param array $coefficients 必需。 与 x 的每个连续乘幂相乘的一组系数。 coefficients 中的值的数量决定了幂级数中的项数
961
     *
962
     * @return double
963
     */
964
    public static function seriessum($x, $n, $m, $coefficients)
965
    {
966
        $c = count($coefficients);
967
        $sum = 0;
968
        for ($i = 0; $i < $c; $i++) {
969
            $sum += $coefficients[$i] * pow($x, $n + ($i - 1) * $m);
970
        }
971
        return $sum;
972
    }
973
974
    /**
975
     * 可在数组中生成一系列连续数字
976
     *
977
     * @param integer $row 要返回的行数
978
     * @param integer $col 要返回的列数
979
     * @param double $start 序列中第一个数字
980
     * @param double $step 数组中每个连续值递增的值
981
     *
982
     * @return array
983
     */
984
    public static function sequence($row, $col, $start = 1, $step = 1)
985
    {
986
        $array = [];
987
        $k = 1;
988
        for ($i = 0; $i < $row; $i++) {
989
            for ($j = 0; $j < $col; $j++) {
990
                $array[$i][$j] = $start + ($k++ - 1) * $step;
991
            }
992
        }
993
        return $array;
994
    }
995
996
    /**
997
     * 确定数字的符号。 如果数字为正数,则返回 1;如果数字为 0,则返回零 (0);如果数字为负数,则返回 -1
998
     *
999
     * @param double $number 必需。 任意实数
1000
     *
1001
     * @return integer
1002
     */
1003
    public static function sign($number)
1004
    {
1005
        return 0 == $number ? 0 : $number / abs($number);
1006
    }
1007
1008
    /**
1009
     * 返回已知角度的正弦
1010
     *
1011
     * @param double $number 必需。 需要求正弦的角度,以弧度表示
1012
     *
1013
     * @return double
1014
     */
1015
    public static function sin($number)
1016
    {
1017
        return sin($number);
1018
    }
1019
1020
    /**
1021
     * 返回数字的双曲正弦
1022
     *
1023
     * - y = sinh(x) = (e^x - e^(-x)) / 2;
1024
     *
1025
     * @param double $number 必需。 任意实数
1026
     *
1027
     * @return double
1028
     */
1029
    public static function sinh($number)
1030
    {
1031
        return sinh($number);
1032
    }
1033
1034
    /**
1035
     * 返回正的平方根
1036
     *
1037
     * @param double $number 必需。 要计算其平方根的数字
1038
     *
1039
     * @return double
1040
     */
1041
    public static function sqrt($number)
1042
    {
1043
        return sqrt($number);
1044
    }
1045
1046
    /**
1047
     * 返回某数与 pi 的乘积的平方根
1048
     *
1049
     * @param double $number 必需。 与 pi 相乘的数
1050
     *
1051
     * @return double
1052
     */
1053
    public static function sqrti($number)
1054
    {
1055
        return sqrt($number * pi());
1056
    }
1057
1058
    /**
1059
     * 返回列表或数据库中的分类汇总
1060
     *
1061
     * @todo
1062
     *
1063
     * @return void
1064
     */
1065
    public static function subtotal()
1066
    {
1067
1068
    }
1069
1070
    /**
1071
     * 可将值相加
1072
     *
1073
     * @param double $number1 要相加的第一个数字
1074
     *
1075
     * @return double
1076
     */
1077
    public static function sum($number1)
1078
    {
1079
        $numbers = is_array($number1) ? $number1 : func_get_args();
1080
        return array_sum($numbers);
1081
    }
1082
1083
    /**
1084
     * 可以使用 SUMIF 函数对 范围 中符合指定条件的值求和
1085
     *
1086
     * - 注意:为保证安全性,不提供此函数
1087
     *
1088
     * @return false
1089
     */
1090
    public static function sumif()
1091
    {
1092
        return false;
1093
    }
1094
1095
    /**
1096
     * 用于计算其满足多个条件的全部参数的总量
1097
     *
1098
     * - 注意:为保证安全性,不提供此函数
1099
     *
1100
     * @return false
1101
     */
1102
    public static function sumifs()
1103
    {
1104
        return false;
1105
    }
1106
1107
    /**
1108
     * 在给定的几组数组中,将数组间对应的元素相乘,并返回乘积之和
1109
     *
1110
     * - 注:office 页面的例子结果应该是 17.58 而不是 21.60
1111
     *
1112
     * @param array $array1 必需。 其相应元素需要进行相乘并求和的第一个数组参数
1113
     *
1114
     * @return double
1115
     */
1116
    public static function sumproduct($array1)
1117
    {
1118
        $arrays = is_array($array1) ? $array1 : func_get_args();
1119
        $arr = [];
1120
        foreach ($arrays as $array) {
1121
            $count = count($array);
1122
            for ($i = 0; $i < $count; $i++) {
1123
                empty($arr[$i]) && $arr[$i] = [];
1124
                array_push($arr[$i], $array[$i]);
1125
            }
1126
        }
1127
        return array_sum(array_map(function ($rows) {
1128
            return array_product($rows);
1129
        }, $arr));
1130
    }
1131
1132
    /**
1133
     * 返回参数的平方和
1134
     *
1135
     * @param double $number1 Number1 是必需的,后续数字是可选的
1136
     *
1137
     * @return double
1138
     */
1139
    public static function sumsq($number1)
1140
    {
1141
        $numbers = is_array($number1) ? $number1 : func_get_args();
1142
        return array_sum(array_map(function ($num) {
1143
            return $num * $num;
1144
        }, $numbers));
1145
    }
1146
1147
    /**
1148
     * 返回两数组中对应数值的平方差之和
1149
     *
1150
     * - y = ∑(x^2 - y^2)
1151
     *
1152
     * @param array $arrayX 必需。 第一个数组或数值区域
1153
     * @param array $arrayY 必需。 第二个数组或数值区域
1154
     *
1155
     * @return double
1156
     */
1157
    public static function sumx2my2($arrayX, $arrayY)
1158
    {
1159
        $count = count($arrayX);
1160
        $sum = 0;
1161
        for ($i = 0; $i < $count; $i++) {
1162
            $sum += pow($arrayX[$i], 2) - pow($arrayY[$i], 2);
1163
        }
1164
        return $sum;
1165
    }
1166
1167
    /**
1168
     * 返回两数组中对应数值的平方和之和
1169
     *
1170
     * - y = ∑(x^2 + y^2)
1171
     *
1172
     * @param array $arrayX 必需。 第一个数组或数值区域
1173
     * @param array $arrayY 必需。 第二个数组或数值区域
1174
     *
1175
     * @return double
1176
     */
1177
    public static function sumx2py2($arrayX, $arrayY)
1178
    {
1179
        $count = count($arrayX);
1180
        $sum = 0;
1181
        for ($i = 0; $i < $count; $i++) {
1182
            $sum += pow($arrayX[$i], 2) + pow($arrayY[$i], 2);
1183
        }
1184
        return $sum;
1185
    }
1186
1187
    /**
1188
     * 返回两数组中对应数值之差的平方和
1189
     *
1190
     * - y = ∑(x - y)^2
1191
     *
1192
     * @param array $arrayX 必需。 第一个数组或数值区域
1193
     * @param array $arrayY 必需。 第二个数组或数值区域
1194
     *
1195
     * @return double
1196
     */
1197
    public static function sumxmy2($arrayX, $arrayY)
1198
    {
1199
        $count = count($arrayX);
1200
        $sum = 0;
1201
        for ($i = 0; $i < $count; $i++) {
1202
            $sum += pow($arrayX[$i] - $arrayY[$i], 2);
1203
        }
1204
        return $sum;
1205
    }
1206
1207
    /**
1208
     * 返回已知角度的正切
1209
     *
1210
     * @param double $number 必需。 要求正切的角度,以弧度表示
1211
     *
1212
     * @return double
1213
     */
1214
    public static function tan($number)
1215
    {
1216
        return tan($number);
1217
    }
1218
1219
    /**
1220
     * 返回数字的双曲正切
1221
     *
1222
     * - y = sinh(x) / cosh(x) = (e^x - e^(-x)) / (e^x + e^(-x))
1223
     *
1224
     * @param double $number 必需。 任意实数
1225
     *
1226
     * @return double
1227
     */
1228
    public static function tanh($number)
1229
    {
1230
        return tanh($number);
1231
    }
1232
1233
    /**
1234
     * 将数字的小数部分截去,返回整数
1235
     *
1236
     * @param double $number 必需。 需要截尾取整的数字
1237
     * @param integer $digits 可选。 用于指定取整精度的数字。 num_digits 的默认值为 0(零)
1238
     *
1239
     * @return double
1240
     */
1241
    public static function trunc($number, $digits = 0)
1242
    {
1243
        $sign = self::sign($number);
1244
        return round(abs($number) - 0.5, $digits) * $sign;
1245
    }
1246
}
1247