63 lines
1.6 KiB
C
63 lines
1.6 KiB
C
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
uint32_t rand32() { return (rand() << 16) | (rand() & 0xFFFF) | 1; }
|
|
|
|
void print_uint128(unsigned __int128 n) {
|
|
if (n == 0) {
|
|
printf("0\n");
|
|
return;
|
|
}
|
|
|
|
// A 128-bit number can have up to 39 decimal digits
|
|
char buffer[40];
|
|
int i = 0;
|
|
|
|
// Extract digits from right to left
|
|
while (n > 0) {
|
|
buffer[i++] = (n % 10) + '0'; // Convert math digit to character
|
|
n /= 10;
|
|
}
|
|
|
|
// Print them in reverse order (left to right)
|
|
while (i > 0) {
|
|
putchar(buffer[--i]);
|
|
}
|
|
putchar('\n');
|
|
}
|
|
|
|
uint64_t rand64() {
|
|
uint64_t r = 0;
|
|
for (int i = 0; i < 4; i++) {
|
|
r = (r << 16) | (rand() & 0xFFFF);
|
|
}
|
|
|
|
// Force the bottom bit to 1, this will make all generated primes odd
|
|
r = r | 1;
|
|
return r;
|
|
}
|
|
|
|
// Stitch two 64-bit random numbers into a 128-bit number
|
|
unsigned __int128 generate_stitched_128() {
|
|
uint64_t top_half = rand64();
|
|
uint64_t bottom_half = rand64();
|
|
|
|
// Cast the top half to 128-bit, shift it over by 64 bits, and attach the bottom
|
|
unsigned __int128 full_number = ((unsigned __int128)top_half << 64) | bottom_half;
|
|
|
|
return full_number;
|
|
}
|
|
|
|
unsigned __int128 generate_prime_candidate() {
|
|
unsigned __int128 candidate = generate_stitched_128();
|
|
|
|
// Force the bottom bit to 1, this will make all generated primes odd
|
|
candidate = candidate | 1;
|
|
|
|
// 3. Force the top bit to 1 (Ensures it is a full 128-bit number)
|
|
candidate = candidate | ((unsigned __int128)1 << 127);
|
|
|
|
return candidate;
|
|
}
|