Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
94.00% |
47 / 50 |
|
80.00% |
4 / 5 |
CRAP | |
0.00% |
0 / 1 |
Prime | |
94.00% |
47 / 50 |
|
80.00% |
4 / 5 |
26.15 | |
0.00% |
0 / 1 |
__construct | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
isMersenne | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
mersenne | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
rabinTest | |
88.89% |
24 / 27 |
|
0.00% |
0 / 1 |
14.27 | |||
sieveOfEratosthenes | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
5 | |||
isPrime | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 |
1 | <?php |
2 | /** |
3 | * Jingga |
4 | * |
5 | * PHP Version 8.1 |
6 | * |
7 | * @package phpOMS\Math\Number |
8 | * @copyright Dennis Eichhorn |
9 | * @license OMS License 2.0 |
10 | * @version 1.0.0 |
11 | * @link https://jingga.app |
12 | */ |
13 | declare(strict_types=1); |
14 | |
15 | namespace phpOMS\Math\Number; |
16 | |
17 | /** |
18 | * Well known functions class. |
19 | * |
20 | * @package phpOMS\Math\Number |
21 | * @license OMS License 2.0 |
22 | * @link https://jingga.app |
23 | * @since 1.0.0 |
24 | */ |
25 | final class Prime |
26 | { |
27 | /** |
28 | * Epsilon for float comparison. |
29 | * |
30 | * @var float |
31 | * @since 1.0.0 |
32 | */ |
33 | public const EPSILON = 4.88e-04; |
34 | |
35 | /** |
36 | * Constructor. |
37 | * |
38 | * @since 1.0.0 |
39 | * @codeCoverageIgnore |
40 | */ |
41 | private function __construct() |
42 | { |
43 | } |
44 | |
45 | /** |
46 | * Is mersenne number? |
47 | * |
48 | * @param int $n Number to test |
49 | * |
50 | * @return bool |
51 | * |
52 | * @since 1.0.0 |
53 | */ |
54 | public static function isMersenne(int $n) : bool |
55 | { |
56 | $mersenne = \log($n + 1, 2); |
57 | |
58 | return $mersenne - (int) $mersenne < self::EPSILON; |
59 | } |
60 | |
61 | /** |
62 | * Get mersenne number |
63 | * |
64 | * @param int $p Power |
65 | * |
66 | * @return int |
67 | * |
68 | * @since 1.0.0 |
69 | */ |
70 | public static function mersenne(int $p) : int |
71 | { |
72 | return (int) (2 ** $p) - 1; |
73 | } |
74 | |
75 | /** |
76 | * Is prime? |
77 | * |
78 | * @param int $n Number to test |
79 | * @param int $k Accuracy |
80 | * |
81 | * @return bool |
82 | * |
83 | * @since 1.0.0 |
84 | */ |
85 | public static function rabinTest(int $n, int $k = 10000) : bool |
86 | { |
87 | if ($n === 2) { |
88 | return true; |
89 | } |
90 | |
91 | if ($n < 2 || $n % 2 === 0) { |
92 | return false; |
93 | } |
94 | |
95 | $d = $n - 1; |
96 | $s = 0; |
97 | |
98 | while ($d % 2 === 0) { |
99 | $d /= 2; |
100 | ++$s; |
101 | } |
102 | |
103 | for ($i = 0; $i < $k; ++$i) { |
104 | $a = \mt_rand(2, $n - 1); |
105 | $x = \bcpowmod((string) $a, (string) $d, (string) $n); |
106 | |
107 | if ($x === false) { |
108 | return false; |
109 | } |
110 | |
111 | if ($x == 1 || $x == $n - 1) { |
112 | continue; |
113 | } |
114 | |
115 | for ($j = 1; $j < $s; ++$j) { |
116 | if ($x === null) { |
117 | return false; |
118 | } |
119 | |
120 | $mul = \bcmul($x, $x); |
121 | /*if ($mul === null) { |
122 | return false; |
123 | }*/ |
124 | |
125 | $x = \bcmod($mul, (string) $n); |
126 | if ($x == 1 || $x === null) { |
127 | return false; |
128 | } |
129 | |
130 | if ($x == $n - 1) { |
131 | continue 2; |
132 | } |
133 | } |
134 | |
135 | return false; |
136 | } |
137 | |
138 | return true; |
139 | } |
140 | |
141 | /** |
142 | * Create prime numbers |
143 | * |
144 | * @param int $n Primes to generate |
145 | * |
146 | * @return int[] |
147 | * |
148 | * @since 1.0.0 |
149 | */ |
150 | public static function sieveOfEratosthenes(int $n) : array |
151 | { |
152 | $number = 2; |
153 | $range = \range(2, $n); |
154 | $primes = \array_combine($range, $range); |
155 | |
156 | if ($primes === false) { |
157 | return []; // @codeCoverageIgnore |
158 | } |
159 | |
160 | while ($number * $number < $n) { |
161 | for ($i = $number; $i <= $n; $i += $number) { |
162 | if ($i === $number) { |
163 | continue; |
164 | } |
165 | |
166 | unset($primes[$i]); |
167 | } |
168 | |
169 | $number = \next($primes); |
170 | } |
171 | |
172 | return \array_values($primes); |
173 | } |
174 | |
175 | /** |
176 | * Is prime? |
177 | * |
178 | * @param int $n Number to test |
179 | * |
180 | * @return bool |
181 | * |
182 | * @since 1.0.0 |
183 | */ |
184 | public static function isPrime(int $n) : bool |
185 | { |
186 | $i = 2; |
187 | |
188 | if ($n === 2) { |
189 | return true; |
190 | } |
191 | |
192 | $sqrtN = \sqrt($n); |
193 | while ($i <= $sqrtN) { |
194 | if ($n % $i === 0) { |
195 | return false; |
196 | } |
197 | |
198 | ++$i; |
199 | } |
200 | |
201 | return true; |
202 | } |
203 | } |