forked from GitHub/gf-core
initial import of the C runtime
This commit is contained in:
154
src/runtime/c/gu/prime.c
Normal file
154
src/runtime/c/gu/prime.c
Normal file
@@ -0,0 +1,154 @@
|
||||
#include <gu/defs.h>
|
||||
#include <gu/assert.h>
|
||||
|
||||
static const uint32_t gu_prime_wheel_mask = 0UL
|
||||
| 1 << 1
|
||||
| 1 << 7
|
||||
| 1 << 11
|
||||
| 1 << 13
|
||||
| 1 << 17
|
||||
| 1 << 19
|
||||
| 1 << 23
|
||||
| 1 << 29;
|
||||
|
||||
static bool
|
||||
gu_prime_wheel(int i)
|
||||
{
|
||||
gu_assert(i >= 0 && i < 30);
|
||||
return !!(gu_prime_wheel_mask & (1 << i));
|
||||
}
|
||||
|
||||
static const uint32_t gu_small_prime_mask = 0UL
|
||||
| 1 << 2
|
||||
| 1 << 3
|
||||
| 1 << 5
|
||||
| 1 << 7
|
||||
| 1 << 11
|
||||
| 1 << 13
|
||||
| 1 << 17
|
||||
| 1 << 19
|
||||
| 1 << 23
|
||||
| 1 << 29
|
||||
| 1U << 31;
|
||||
|
||||
static bool
|
||||
gu_is_wheel_prime(int u)
|
||||
{
|
||||
gu_assert(u > 30 && u % 2 != 0 && u % 3 != 0 && u % 5 != 0);
|
||||
int d = 0;
|
||||
int i = 7;
|
||||
goto start;
|
||||
while (d * d <= u) {
|
||||
for (i = 1; i <= 29; i+=2) {
|
||||
start:
|
||||
if (gu_prime_wheel(i) && u % (d + i) == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
d += 30;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
gu_prime_inf(int i)
|
||||
{
|
||||
if (i < 2) {
|
||||
return 0;
|
||||
} else if (i < 32) {
|
||||
while (!(gu_small_prime_mask & (1 << i))) {
|
||||
i--;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int d = (i - 1) | 1;
|
||||
int r = d % 30;
|
||||
|
||||
while (!gu_prime_wheel(r) || !gu_is_wheel_prime(d)) {
|
||||
d -= 2;
|
||||
r -= 2;
|
||||
if (r < 0) {
|
||||
r += 30;
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
int
|
||||
gu_prime_sup(int i)
|
||||
{
|
||||
if (i <= 2) {
|
||||
return 2;
|
||||
} else if (i < 32) {
|
||||
while (!(gu_small_prime_mask & (1 << i))) {
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int d = i | 1;
|
||||
int r = d % 30;
|
||||
|
||||
while (!gu_prime_wheel(r) || !gu_is_wheel_prime(d)) {
|
||||
d += 2;
|
||||
r += 2;
|
||||
if (r > 30) {
|
||||
r -= 30;
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
bool
|
||||
gu_is_prime(int i)
|
||||
{
|
||||
if (i < 2) {
|
||||
return false;
|
||||
} else if (i < 30) {
|
||||
return !!(gu_small_prime_mask & (1 << i));
|
||||
} else if (!gu_prime_wheel(i % 30)) {
|
||||
return false;
|
||||
} else {
|
||||
return gu_is_wheel_prime(i);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
gu_is_twin_prime(int i)
|
||||
{
|
||||
return gu_is_prime(i) && gu_is_prime(i - 2);
|
||||
}
|
||||
|
||||
int
|
||||
gu_twin_prime_inf(int i)
|
||||
{
|
||||
while (true) {
|
||||
i = gu_prime_inf(i);
|
||||
if (i == 0) {
|
||||
return 0;
|
||||
} else if (gu_is_prime(i - 2)) {
|
||||
return i;
|
||||
}
|
||||
i = i - 4;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
gu_twin_prime_sup(int i)
|
||||
{
|
||||
if (i <= 5) {
|
||||
return 5;
|
||||
}
|
||||
i = i - 2;
|
||||
while (true) {
|
||||
i = gu_prime_sup(i);
|
||||
if (gu_is_prime(i + 2)) {
|
||||
return i + 2;
|
||||
}
|
||||
i = i + 4;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user