Change to new GCD function
This commit is contained in:
parent
4af0adf350
commit
b7ed7e230a
150
main.c
150
main.c
@ -111,13 +111,12 @@ static void print_arg_error(const char *arg);
|
|||||||
static void print_help_and_exit(void);
|
static void print_help_and_exit(void);
|
||||||
static void print_version_and_exit(void);
|
static void print_version_and_exit(void);
|
||||||
static void print_info_and_exit(void);
|
static void print_info_and_exit(void);
|
||||||
static unsigned long find_gcf(unsigned long *nums, size_t len);
|
|
||||||
static unsigned long *find_prime_factors(unsigned long n, size_t *out_len);
|
|
||||||
static void initialize_modules(void);
|
static void initialize_modules(void);
|
||||||
|
static unsigned long gcd(unsigned long n1, unsigned long n2);
|
||||||
|
static unsigned long find_module_refresh_time(void);
|
||||||
static void set_refresh_time(void);
|
static void set_refresh_time(void);
|
||||||
static void signal_handler(int signum);
|
static void signal_handler(int signum);
|
||||||
static void setup_signals(void);
|
static void setup_signals(void);
|
||||||
static unsigned long find_module_refresh_gcf(void);
|
|
||||||
static unsigned long timespec_to_miliseconds(struct timespec *ts);
|
static unsigned long timespec_to_miliseconds(struct timespec *ts);
|
||||||
static void miliseconds_to_timespec(unsigned long ms, struct timespec *out_ts);
|
static void miliseconds_to_timespec(unsigned long ms, struct timespec *out_ts);
|
||||||
static void do_initial_refresh(void);
|
static void do_initial_refresh(void);
|
||||||
@ -431,102 +430,6 @@ static void print_info_and_exit(void) {
|
|||||||
qtb_exit();
|
qtb_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long find_gcf(unsigned long *nums, size_t len) {
|
|
||||||
if (len == 0) { /* gcf(0) = 0 */
|
|
||||||
return 0;
|
|
||||||
} else if (len == 1) { /* gcf(n) = n */
|
|
||||||
return nums[0];
|
|
||||||
}
|
|
||||||
/* calculate all prime factors */
|
|
||||||
unsigned long **prime_factors = NULL;
|
|
||||||
size_t prime_factors_length = 0;
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < len; ++i) {
|
|
||||||
unsigned long *i_prime_factors = find_prime_factors(nums[i], NULL);
|
|
||||||
prime_factors = qtb_realloc(prime_factors, sizeof(unsigned long *) *
|
|
||||||
++prime_factors_length);
|
|
||||||
prime_factors[prime_factors_length - 1] = i_prime_factors;
|
|
||||||
}
|
|
||||||
/* find which calculated prime factors are common to all inputs */
|
|
||||||
unsigned long *common_factors = NULL;
|
|
||||||
size_t common_factors_length = 0;
|
|
||||||
unsigned long *j;
|
|
||||||
/* loop though each factor in prime_factors[0] */
|
|
||||||
for (j = prime_factors[0]; *j != 0; ++j) {
|
|
||||||
/* loop though every set of factors except prime_factors[0] */
|
|
||||||
/* size_t i; */
|
|
||||||
for (i = 1; i < prime_factors_length; ++i) {
|
|
||||||
unsigned long *i_prime_factors;
|
|
||||||
for (i_prime_factors = prime_factors[i]; *i_prime_factors != 0;
|
|
||||||
++i_prime_factors) {
|
|
||||||
if (*i_prime_factors == *j) {
|
|
||||||
*i_prime_factors = 4; /* remove the factor (by setting it to
|
|
||||||
a composite number) */
|
|
||||||
goto found_factor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* the factor was not found, therefore we can't add it */
|
|
||||||
goto dont_add;
|
|
||||||
/* we found the factor, check the next set of factors */
|
|
||||||
found_factor:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* the factor was a common factor, add it */
|
|
||||||
common_factors = qtb_realloc(
|
|
||||||
common_factors, sizeof(unsigned long) * ++common_factors_length);
|
|
||||||
common_factors[common_factors_length - 1] = *j;
|
|
||||||
/* the factor was not a common factor */
|
|
||||||
dont_add:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
/* qtb_free sets of factors */
|
|
||||||
/* size_t i; */
|
|
||||||
for (i = 0; i < prime_factors_length; ++i) {
|
|
||||||
qtb_free(prime_factors[i]);
|
|
||||||
}
|
|
||||||
qtb_free(prime_factors);
|
|
||||||
/* finally, calculate the gcf */
|
|
||||||
unsigned long gcf = 1;
|
|
||||||
/* size_t i; */
|
|
||||||
for (i = 0; i < common_factors_length; ++i) {
|
|
||||||
gcf *= common_factors[i];
|
|
||||||
}
|
|
||||||
qtb_free(common_factors);
|
|
||||||
return gcf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return value will be 0 terminated. if out_len is not NULL,
|
|
||||||
it's value will be set to the number of primes found (length of return value
|
|
||||||
- 1) */
|
|
||||||
static unsigned long *find_prime_factors(unsigned long n, size_t *out_len) {
|
|
||||||
unsigned long *out_arr = NULL;
|
|
||||||
size_t arr_len = 0;
|
|
||||||
while (n % 2 == 0) {
|
|
||||||
out_arr = qtb_realloc(out_arr, sizeof(unsigned long) * ++arr_len);
|
|
||||||
out_arr[arr_len - 1] = 2;
|
|
||||||
n /= 2;
|
|
||||||
}
|
|
||||||
unsigned long i;
|
|
||||||
for (i = 3; i <= sqrtl(n); i += 2) {
|
|
||||||
while (n % i == 0) {
|
|
||||||
out_arr =
|
|
||||||
qtb_realloc(out_arr, sizeof(unsigned long) * ++arr_len);
|
|
||||||
out_arr[arr_len - 1] = i;
|
|
||||||
n /= i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (n > 2) {
|
|
||||||
out_arr = qtb_realloc(out_arr, sizeof(unsigned long) * ++arr_len);
|
|
||||||
out_arr[arr_len - 1] = n;
|
|
||||||
}
|
|
||||||
out_arr = qtb_realloc(out_arr, sizeof(unsigned long) * arr_len);
|
|
||||||
out_arr[arr_len] = 0;
|
|
||||||
if (out_len) {
|
|
||||||
*out_len = arr_len;
|
|
||||||
}
|
|
||||||
return out_arr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void initialize_modules() {
|
static void initialize_modules() {
|
||||||
int has_error = FALSE;
|
int has_error = FALSE;
|
||||||
size_t i;
|
size_t i;
|
||||||
@ -552,11 +455,42 @@ static void initialize_modules() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned long gcd(unsigned long n1, unsigned long n2) {
|
||||||
|
if (n1 == 0) {
|
||||||
|
return n2;
|
||||||
|
}
|
||||||
|
return gcd(n2 % n1, n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long find_module_refresh_time() {
|
||||||
|
size_t i;
|
||||||
|
size_t ignore_index;
|
||||||
|
size_t result;
|
||||||
|
for (i = 0; i < global_module_count; ++i) {
|
||||||
|
if (!modules[i].disabled && modules[i].refresh_time != NO_REFRESH) {
|
||||||
|
result = modules[i].refresh_time;
|
||||||
|
ignore_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (i = 0; i < global_module_count; ++i) {
|
||||||
|
if (i == ignore_index) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!modules[i].disabled && modules[i].refresh_time != NO_REFRESH) {
|
||||||
|
result = gcd(result, modules[i].refresh_time);
|
||||||
|
}
|
||||||
|
if (result == 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static void set_refresh_time() {
|
static void set_refresh_time() {
|
||||||
#ifdef REFRESH_TIME
|
#ifdef REFRESH_TIME
|
||||||
unsigned long refresh_ms = REFRESH_TIME;
|
unsigned long refresh_ms = REFRESH_TIME;
|
||||||
#else
|
#else
|
||||||
unsigned long refresh_ms = find_module_refresh_gcf();
|
unsigned long refresh_ms = find_module_refresh_time();
|
||||||
if (refresh_ms == 0) { /* if all modules are triggered by signals */
|
if (refresh_ms == 0) { /* if all modules are triggered by signals */
|
||||||
refresh_ms = HOURS(1); /* refresh once an hour */
|
refresh_ms = HOURS(1); /* refresh once an hour */
|
||||||
}
|
}
|
||||||
@ -600,22 +534,6 @@ static void setup_signals() {
|
|||||||
sigprocmask(SIG_BLOCK, &global_real_time_mask, NULL);
|
sigprocmask(SIG_BLOCK, &global_real_time_mask, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long find_module_refresh_gcf() {
|
|
||||||
size_t refresh_times_length = 0;
|
|
||||||
unsigned long *refresh_times = NULL;
|
|
||||||
size_t i;
|
|
||||||
for (i = 0; i < global_module_count; ++i) {
|
|
||||||
if (!modules[i].disabled && modules[i].refresh_time != NO_REFRESH) {
|
|
||||||
refresh_times = qtb_realloc(
|
|
||||||
refresh_times, sizeof(unsigned long) * ++refresh_times_length);
|
|
||||||
refresh_times[refresh_times_length - 1] = modules[i].refresh_time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unsigned long gcf = find_gcf(refresh_times, refresh_times_length);
|
|
||||||
qtb_free(refresh_times);
|
|
||||||
return gcf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned long timespec_to_miliseconds(struct timespec *ts) {
|
static unsigned long timespec_to_miliseconds(struct timespec *ts) {
|
||||||
return (ts->tv_sec * 1000) + (ts->tv_nsec / 1000000);
|
return (ts->tv_sec * 1000) + (ts->tv_nsec / 1000000);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user