Skip to content

Instantly share code, notes, and snippets.

@marsgpl
Created May 29, 2025 07:02
Show Gist options
  • Save marsgpl/d76e2cd687afd66f4322944f482cddc7 to your computer and use it in GitHub Desktop.
Save marsgpl/d76e2cd687afd66f4322944f482cddc7 to your computer and use it in GitHub Desktop.
check whether a number is a prime or not
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
static void error(const char *message, ...) {
va_list args;
fprintf(stderr, "\e[31mError:\e[0m ");
va_start(args, message);
vfprintf(stderr, message, args);
va_end(args);
fprintf(stderr, "\n");
exit(1);
}
// string must be null-terminated
static uint64_t string_to_uint64(const char *string) {
uint64_t result = 0;
int index = 0;
const int MAX_DIGITS = 20; // 18,446,744,073,709,551,615
while (1) {
char c = string[index++];
switch (c) {
case '\0': {
if (index == 1) {
error("string is empty");
} else {
return result;
}
}
case '0' ... '9': {
if (index > MAX_DIGITS) {
error("too many digits, uint64_t overflow");
}
// TODO check overflow for max value
result = result * 10 + c - '0';
break;
}
default: {
error("unexpected 'x%02X' at index %d", c, index - 1);
}
}
}
}
int is_prime(uint64_t number) {
switch (number) {
case 0: case 1: case 4: case 6: case 8: case 9:
return 0; // not
case 2: case 3: case 5: case 7:
return 1; // prime
}
if (number % 2 == 0) {
return 0; // even, not a prime
}
// check other divisors
// TODO requires heavy optimization
// += 2 because all other divisors are even
for (uint64_t divisor = 3; divisor < number; divisor += 2) {
if (number % divisor == 0) {
printf("divisor: %llu\n", divisor);
return 0; // not
}
}
return 1; // prime
}
int main(int argc, char **argv) {
// argv[0] is program name
if (argc != 2) {
error("Usage: prime 123");
}
uint64_t number = string_to_uint64(argv[1]);
if (is_prime(number)) {
printf("number %llu is prime\n", number);
} else {
printf("number %llu is NOT a prime\n", number);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment