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_version_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 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 signal_handler(int signum);
|
||||
static void setup_signals(void);
|
||||
static unsigned long find_module_refresh_gcf(void);
|
||||
static unsigned long timespec_to_miliseconds(struct timespec *ts);
|
||||
static void miliseconds_to_timespec(unsigned long ms, struct timespec *out_ts);
|
||||
static void do_initial_refresh(void);
|
||||
@ -431,102 +430,6 @@ static void print_info_and_exit(void) {
|
||||
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() {
|
||||
int has_error = FALSE;
|
||||
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() {
|
||||
#ifdef REFRESH_TIME
|
||||
unsigned long refresh_ms = REFRESH_TIME;
|
||||
#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 */
|
||||
refresh_ms = HOURS(1); /* refresh once an hour */
|
||||
}
|
||||
@ -600,22 +534,6 @@ static void setup_signals() {
|
||||
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) {
|
||||
return (ts->tv_sec * 1000) + (ts->tv_nsec / 1000000);
|
||||
}
|
||||
|
Reference in New Issue
Block a user