Fixed small bug, increased Fib efficiency and changed to C++ gmp classes

This commit is contained in:
2018-11-14 11:58:33 -05:00
parent aed6b8672c
commit 6e73189e96

View File

@@ -11,7 +11,7 @@
#include <cinttypes> #include <cinttypes>
#include <algorithm> #include <algorithm>
#include <string> #include <string>
#include <gmp.h> //This is necessary for the getFib function for numbers larger than a normal int can hold. It can be commented out if needed #include <gmpxx.h> //This is necessary for the getGmpFib function for numbers larger than a normal int can hold. It can be commented out if needed
namespace mee{ namespace mee{
@@ -49,8 +49,6 @@ std::vector<T> getPrimes(T goalNumber){
return primes; return primes;
} }
//1 divides everything
primes.push_back(1);
//If the number is even 2 is a factor //If the number is even 2 is a factor
if((goalNumber % 2) == 0){ if((goalNumber % 2) == 0){
primes.push_back(2); primes.push_back(2);
@@ -81,7 +79,7 @@ template<class T>
std::vector<T> getDivisors(T num){ std::vector<T> getDivisors(T num){
std::vector<T> divisors; //Holds the number of divisors std::vector<T> divisors; //Holds the number of divisors
//You only need to go to sqrt(number). cnt * cnt is faster than sqrt() //You only need to go to sqrt(number). cnt * cnt is faster than sqrt()
for(int cnt = 1;cnt * cnt <= num;++cnt){ for(uint64_t cnt = 1;cnt * cnt <= num;++cnt){
//Check if the counter evenly divides the number //Check if the counter evenly divides the number
//If it does the counter and the other number are both divisors //If it does the counter and the other number are both divisors
if((num % cnt) == 0){ if((num % cnt) == 0){
@@ -155,53 +153,36 @@ uint64_t getFib(uint64_t num){
//Setup the variables //Setup the variables
uint64_t fib = 0; uint64_t fib = 0;
uint64_t tempNums[3]; uint64_t tempNums[3];
tempNums[0] = tempNums[2] = 1; tempNums[0] = tempNums[1] = 1;
//Do the calculation //Do the calculation
uint64_t cnt = 2; for(uint64_t cnt = 2;cnt < num;++cnt){
uint64_t location = 1; tempNums[cnt % 3] = tempNums[(cnt + 1) % 3] + tempNums[(cnt + 2) % 3];
while(cnt < num){
tempNums[location] = tempNums[(location + 1) % 3] + tempNums[(location + 2) % 3];
location = (location + 1) % 3;
++cnt;
} }
fib = tempNums[(num + 1) % 3]; //Transfer the answer to permanent variable fib = tempNums[(num - 1) % 3]; //Transfer the answer to permanent variable. -1 to account for the offset of starting at 0
return fib; return fib;
} }
void getFib(mpz_t fibNum, uint64_t num){ mpz_class getMpzFib(uint64_t num){
//Make sure the number is within bounds //Make sure the number is within bounds
if(num <= 0){ if(num <= 0){
mpz_set_ui(fibNum, 0); return 0;
return;
} }
else if(num <= 2){ else if(num <= 2){
mpz_set_ui(fibNum, 1); return 1;
return;
} }
mpz_t tempNums[3]; mpz_class fibNum = 0;
mpz_class tempNums[3];
//Initialize the variables //Initialize the variables
mpz_init(tempNums[0]); tempNums[0] = 1;
mpz_init(tempNums[1]); tempNums[1] = 1;
mpz_init(tempNums[2]);
//Set the variables correctly
mpz_set_ui(tempNums[0], 1);
mpz_set_ui(tempNums[2], 1);
//Do the calculation //Do the calculation
uint64_t cnt = 2; for(uint64_t cnt = 2;cnt < num;++cnt){
uint64_t location = 1; tempNums[cnt % 3] = tempNums[(cnt + 1) % 3] + tempNums[(cnt + 2) % 3];
while(cnt < num){
mpz_add(tempNums[location], tempNums[(location + 1) % 3], tempNums[(location + 2) % 3]);
location = (location + 1) % 3;
++cnt;
} }
mpz_set(fibNum, tempNums[(num + 1) % 3]); //Transfer the answer to the permanent variable
//Clear the variables return tempNums[(num - 1) % 3]; //Return the answer
mpz_clear(tempNums[0]);
mpz_clear(tempNums[1]);
mpz_clear(tempNums[2]);
} }
} }