Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated functions to vector format #25

Open
wants to merge 7 commits into
base: base-2-to-the-64
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/BigInt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
#define BIG_INT_HPP

#include <iostream>
#include <stdint.h>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change this to <cstdint>.

#include <vector>

class BigInt {
std::vector<unsigned long long> magnitude;
std::vector<uint64_t> magnitude;
bool is_negative;

public:
Expand Down
26 changes: 17 additions & 9 deletions include/constructors/constructors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,21 @@
-------------------
*/

BigInt::BigInt() {
magnitude = { 0 };
is_negative = false;
}
BigInt::BigInt()
: magnitude(1,0)
, is_negative(false)
{ }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lines shouldn't start with a grammar symbol (like commas and colons):

BigInt::BigInt():
        magnitude(1, 0),
        is_negative(false) { }



/*
Copy constructor
----------------
*/

BigInt::BigInt(const BigInt& num) {
magnitude = num.magnitude;
is_negative = num.is_negative;
}
BigInt::BigInt(const BigInt& num)
: magnitude(num.magnitude)
, is_negative(num.is_negative)
{ }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same suggestion as above.



/*
Expand All @@ -39,7 +39,15 @@ BigInt::BigInt(const BigInt& num) {
*/

BigInt::BigInt(const long long& num) {
magnitude = { (unsigned long long) llabs(num) };
if (sizeof(long long) == (sizeof(uint64_t)))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of these checks at multiple places, I suggest we change all occurrences of long long to int64_t and unsigned long long to uint64_t.

magnitude = { (uint64_t) llabs(num) };

// If size not equal, long long will be bigger
else {
magnitude.push_back((uint64_t)llabs((uint64_t)num));
if (num / UINT64_MAX > 0)
magnitude.push_back((uint64_t)llabs(num / UINT64_MAX));
}
is_negative = num < 0;
}

Expand Down
12 changes: 10 additions & 2 deletions include/functions/conversion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,16 @@
*/

std::string BigInt::to_string() const {
// prefix with sign if negative
return this->sign == '-' ? "-" + this->value : this->value;

std::string num_string;

for (uint64_t ull : this->magnitude)
while (ull > 0) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wouldn't work. Base conversion will need to be done. I'm working on it, so you can leave this as it previously was.

num_string += ((ull % 10) + '0');
ull /= 10;
}

return this->is_negative ? "-" + num_string : num_string;
}


Expand Down
15 changes: 7 additions & 8 deletions include/functions/random.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,13 @@ BigInt big_random(size_t num_digits = 0) {
// use a random number for it:
num_digits = 1 + rand_generator() % MAX_RANDOM_LENGTH;

BigInt big_rand;
big_rand.value = ""; // clear value to append digits
while (big_rand.value.size() < num_digits)
big_rand.value += std::to_string(rand_generator());
if (big_rand.value.size() != num_digits)
big_rand.value.erase(num_digits); // erase extra digits

return big_rand;
std::string random_value = "";
while (random_value.size() < num_digits)
random_value += std::to_string(rand_generator());
if (random_value.size() != num_digits)
random_value.erase(num_digits); // erase extra digits

return BigInt(random_value);
}


Expand Down
77 changes: 76 additions & 1 deletion include/functions/utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#define BIG_INT_UTILITY_FUNCTIONS_HPP

#include <tuple>
#include <stdint.h>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please change this to <cstdint>.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct me if i'm wrong, would that require every reference to uint64_t to be prefixed with std::?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because in other c++ code that I've seen they don't use the std:: prefix

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, you wouldn't need the std:: namespace for int64_t and uint64_t

#include <limits>


/*
Expand Down Expand Up @@ -93,7 +95,6 @@ std::tuple<std::string, std::string> get_larger_and_smaller(const std::string& n
return std::make_tuple(larger, smaller);
}


/*
is_power_of_10
----------------------
Expand All @@ -110,4 +111,78 @@ bool is_power_of_10(const std::string& num){
return true; // first digit is 1 and the following digits are all 0
}


/*--------------------- Vector functions ---------------------*/

/*
add_leading_zeroes
------------------
Adds a given number of leading zeroes to a string-represented integer `num`.
*/

void add_leading_zeroes(std::vector<uint64_t>& num, size_t num_zeroes) {
std::vector<uint64_t> tmp(num_zeroes, 0);
tmp.insert(tmp.end(), num.begin(), num.end());
num = tmp;
}


/*
add_trailing_zeroes
-------------------
Adds a given number of trailing zeroes to a string-represented integer `num`.
*/

void add_trailing_zeroes(std::vector<uint64_t>& num, size_t num_zeroes) {
std::vector<uint64_t> tmp(num_zeroes, 0);
num.insert(num.end(), tmp.begin(), tmp.end());
}

/*
strip_leading_zeroes
--------------------
Strip the leading zeroes from a number represented as a vector.
*/

void strip_trailing_zeroes(std::vector<uint64_t>& num) {
for (auto digit_itter = num.rbegin(); digit_itter != num.rend(); digit_itter++)
if (*digit_itter != 0) {
num = std::vector<uint64_t>(num.rend(), digit_itter + 1);
return;
}

// If all 0's
num.clear();
num.push_back(0);
}

/*
get_larger_and_smaller
----------------------
Identifies the given vector-represented integers as `larger` and `smaller`,
padding the smaller number with leading zeroes to make it equal in length to
the larger number.
Note: for simplicity and efficiency, this function only compares length and not value.
*/

std::tuple<std::vector<uint64_t>, std::vector<uint64_t>> get_larger_and_smaller(const std::vector<uint64_t>& num1,
const std::vector<uint64_t>& num2) {
std::vector<uint64_t> larger, smaller;
if (num1.size() > num2.size()) {
larger = num1;
smaller = num2;
}
else {
larger = num2;
smaller = num1;
}

// pad the smaller number with zeroes
add_trailing_zeroes(smaller, larger.size() - smaller.size());

return std::make_tuple(larger, smaller);
}



#endif // BIG_INT_UTILITY_FUNCTIONS_HPP
12 changes: 6 additions & 6 deletions include/operators/assignment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
*/

BigInt& BigInt::operator=(const BigInt& num) {
value = num.value;
sign = num.sign;
magnitude = num.magnitude;
is_negative = num.is_negative;

return *this;
}
Expand All @@ -31,8 +31,8 @@ BigInt& BigInt::operator=(const BigInt& num) {

BigInt& BigInt::operator=(const long long& num) {
BigInt temp(num);
value = temp.value;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eliminating the constructor call here would be a good idea.

sign = temp.sign;
magnitude = temp.magnitude;
is_negative = temp.is_negative;

return *this;
}
Expand All @@ -45,8 +45,8 @@ BigInt& BigInt::operator=(const long long& num) {

BigInt& BigInt::operator=(const std::string& num) {
BigInt temp(num);
value = temp.value;
sign = temp.sign;
magnitude = temp.magnitude;
is_negative = temp.is_negative;

return *this;
}
Expand Down
Loading