From c892cbadc630bac45ea9ffbb2bada8a427187bba Mon Sep 17 00:00:00 2001 From: Krishna Vedala <7001608+kvedala@users.noreply.github.com> Date: Tue, 26 May 2020 18:07:41 -0400 Subject: [PATCH] fixed code for lint and copy constructor --- others/fibonacci_large.cpp | 7 +- others/large_number.h | 470 +++++++++++++++++++------------------ 2 files changed, 244 insertions(+), 233 deletions(-) diff --git a/others/fibonacci_large.cpp b/others/fibonacci_large.cpp index 0333feb81..6f36702a2 100644 --- a/others/fibonacci_large.cpp +++ b/others/fibonacci_large.cpp @@ -18,11 +18,12 @@ large_number fib(uint64_t n) { large_number f1(1); do { - large_number f2 = f0 + f1; - f0 = f1; - f1 = f2; + large_number f2 = f1; + f1 += f0; + f0 = f2; n--; } while (n > 2); // since we start from 2 + return f1; } diff --git a/others/large_number.h b/others/large_number.h index 38d9125de..8ea8190b6 100644 --- a/others/large_number.h +++ b/others/large_number.h @@ -1,4 +1,5 @@ /** + * @file * @author Krishna Vedala * @email krishna (dot) vedala (at) ieee (dot) org **/ @@ -21,252 +22,261 @@ **/ class large_number { public: - /**< initializer with value = 1 */ - large_number() { _digits.push_back(1); } + /**< initializer with value = 1 */ + large_number() { _digits.push_back(1); } - /**< initializer from an integer */ - explicit large_number(uint64_t n) { - uint64_t carry = n; - do { - add_digit(carry % 10); - carry /= 10; - } while (carry != 0); - } + // /**< initializer from an integer */ + // explicit large_number(uint64_t n) { + // uint64_t carry = n; + // do { + // add_digit(carry % 10); + // carry /= 10; + // } while (carry != 0); + // } - /**< initializer from another large_number */ - explicit large_number(const large_number &a) { _digits = a._digits; } - - /**< initializer from a vector */ - explicit large_number(const std::vector &vec) { - _digits = vec; - } - - /**< initializer from a string */ - explicit large_number(const char *number_str) { - for (size_t i = strlen(number_str); i > 0; i--) { - unsigned char a = number_str[i - 1] - '0'; - if (a >= 0 && a <= 9) _digits.push_back(a); - } - } - - /** - * Function to check implementation - **/ - static bool test() { - std::cout << "------ Checking `large_number` class implementations\t" - << std::endl; - large_number a(40); - // 1. test multiplication - a *= 10; - if (a != large_number(400)) { - std::cerr << "\tFailed 1/6 (" << a << "!=400)" << std::endl; - return false; - } - std::cout << "\tPassed 1/6..."; - // 2. test compound addition with integer - a += 120; - if (a != large_number(520)) { - std::cerr << "\tFailed 2/6 (" << a << "!=520)" << std::endl; - return false; - } - std::cout << "\tPassed 2/6..."; - // 3. test compound multiplication again - a *= 10; - if (a != large_number(5200)) { - std::cerr << "\tFailed 3/6 (" << a << "!=5200)" << std::endl; - return false; - } - std::cout << "\tPassed 3/6..."; - // 4. test increment (prefix) - ++a; - if (a != large_number(5201)) { - std::cerr << "\tFailed 4/6 (" << a << "!=5201)" << std::endl; - return false; - } - std::cout << "\tPassed 4/6..."; - // 5. test increment (postfix) - a++; - if (a != large_number(5202)) { - std::cerr << "\tFailed 5/6 (" << a << "!=5202)" << std::endl; - return false; - } - std::cout << "\tPassed 5/6..."; - // 6. test addition with another large number - a = a + large_number("7000000000000000000000000000000"); - if (a != large_number("7000000000000000000000000005202")) { - std::cerr << "\tFailed 6/6 (" << a << "!=7000000000000000000000000005202)" - << std::endl; - return false; - } - std::cout << "\tPassed 6/6..." << std::endl; - return true; - } - - /** - * add a digit at MSB to the large number - **/ - void add_digit(unsigned int value) { - if (value > 9) { - std::cerr << "digit > 9!!\n"; - exit(EXIT_FAILURE); + /**< initializer from an integer */ + explicit large_number(int n) { + int carry = n; + do { + add_digit(carry % 10); + carry /= 10; + } while (carry != 0); } - _digits.push_back(value); - } + /**< initializer from another large_number */ + large_number(const large_number &a) : _digits(a._digits) {} - /** - * Get number of digits in the number - **/ - const size_t num_digits() const { return _digits.size(); } + /**< initializer from a vector */ + explicit large_number(std::vector &vec) : _digits(vec) {} - /** - * operator over load to access the - * i^th digit conveniently and also - * assign value to it - **/ - inline unsigned char &operator[](size_t n) { return this->_digits[n]; } - - inline const unsigned char &operator[](size_t n) const { - return this->_digits[n]; - } - - /** - * operator overload to compare two numbers - **/ - friend std::ostream &operator<<(std::ostream &out, const large_number &a) { - for (size_t i = a.num_digits(); i > 0; i--) - out << static_cast(a[i - 1]); - return out; - } - - /** - * operator overload to compare two numbers - **/ - friend bool operator==(large_number const &a, large_number const &b) { - size_t N = a.num_digits(); - if (N != b.num_digits()) return false; - for (size_t i = 0; i < N; i++) - if (a[i] != b[i]) return false; - return true; - } - - /** - * operator overload to compare two numbers - **/ - friend bool operator!=(large_number const &a, large_number const &b) { - return !(a == b); - } - - /** - * operator overload to increment (prefix) - **/ - large_number &operator++() { - (*this) += 1; - return *this; - } - - /** - * operator overload to increment (postfix) - **/ - large_number operator++(int) { - large_number tmp(_digits); - ++(*this); - return tmp; - } - - /** - * operator overload to add - **/ - template - large_number &operator+=(T n) { - // if adding with another large_number - if (typeid(T) == typeid(large_number)) { - large_number *b = static_cast(&n); - const size_t max_L = std::max(this->num_digits(), b->num_digits()); - unsigned int carry = 0; - size_t i; - for (i = 0; i < max_L || carry != 0; i++) { - if (i < b->num_digits()) carry += (*b)[i]; - if (i < this->num_digits()) carry += (*this)[i]; - if (i < this->num_digits()) - (*this)[i] = carry % 10; - else - this->add_digit(carry % 10); - carry /= 10; - } - } else if (std::is_integral::value) { - return (*this) += large_number(n); - } else { - std::cerr << "Must be integer addition unsigned integer types." - << std::endl; + /**< initializer from a string */ + explicit large_number(char const *number_str) { + for (size_t i = strlen(number_str); i > 0; i--) { + unsigned char a = number_str[i - 1] - '0'; + if (a >= 0 && a <= 9) _digits.push_back(a); + } } - return *this; - } - /** - * operator overload to perform addition - **/ - template - friend large_number &operator+(large_number &a, const T &b) { - a += b; - return a; - } + /** + * Function to check implementation + **/ + static bool test() { + std::cout << "------ Checking `large_number` class implementations\t" + << std::endl; + large_number a(40); + // 1. test multiplication + a *= 10; + if (a != large_number(400)) { + std::cerr << "\tFailed 1/6 (" << a << "!=400)" << std::endl; + return false; + } + std::cout << "\tPassed 1/6..."; + // 2. test compound addition with integer + a += 120; + if (a != large_number(520)) { + std::cerr << "\tFailed 2/6 (" << a << "!=520)" << std::endl; + return false; + } + std::cout << "\tPassed 2/6..."; + // 3. test compound multiplication again + a *= 10; + if (a != large_number(5200)) { + std::cerr << "\tFailed 3/6 (" << a << "!=5200)" << std::endl; + return false; + } + std::cout << "\tPassed 3/6..."; + // 4. test increment (prefix) + ++a; + if (a != large_number(5201)) { + std::cerr << "\tFailed 4/6 (" << a << "!=5201)" << std::endl; + return false; + } + std::cout << "\tPassed 4/6..."; + // 5. test increment (postfix) + a++; + if (a != large_number(5202)) { + std::cerr << "\tFailed 5/6 (" << a << "!=5202)" << std::endl; + return false; + } + std::cout << "\tPassed 5/6..."; + // 6. test addition with another large number + a = a + large_number("7000000000000000000000000000000"); + if (a != large_number("7000000000000000000000000005202")) { + std::cerr << "\tFailed 6/6 (" << a + << "!=7000000000000000000000000005202)" << std::endl; + return false; + } + std::cout << "\tPassed 6/6..." << std::endl; + return true; + } - /** - * assignment operator - **/ - void operator=(const large_number &b) { _digits = b._digits; } + /** + * add a digit at MSB to the large number + **/ + void add_digit(unsigned int value) { + if (value > 9) { + std::cerr << "digit > 9!!\n"; + exit(EXIT_FAILURE); + } - /** - * operator overload to increment - **/ - template - large_number &operator*=(const T n) { - static_assert(std::is_integral::value, - "Must be integer addition unsigned integer types."); - this->multiply(n); - return *this; - } + _digits.push_back(value); + } - /** - * returns i^th digit as an ASCII character - **/ - const char digit_char(size_t i) const { - return _digits[num_digits() - i - 1] + '0'; - } + /** + * Get number of digits in the number + **/ + const size_t num_digits() const { return _digits.size(); } + + /** + * operator over load to access the + * i^th digit conveniently and also + * assign value to it + **/ + inline unsigned char &operator[](size_t n) { return this->_digits[n]; } + + inline const unsigned char &operator[](size_t n) const { + return this->_digits[n]; + } + + /** + * operator overload to compare two numbers + **/ + friend std::ostream &operator<<(std::ostream &out, const large_number &a) { + for (size_t i = a.num_digits(); i > 0; i--) + out << static_cast(a[i - 1]); + return out; + } + + /** + * operator overload to compare two numbers + **/ + friend bool operator==(large_number const &a, large_number const &b) { + size_t N = a.num_digits(); + if (N != b.num_digits()) return false; + for (size_t i = 0; i < N; i++) + if (a[i] != b[i]) return false; + return true; + } + + /** + * operator overload to compare two numbers + **/ + friend bool operator!=(large_number const &a, large_number const &b) { + return !(a == b); + } + + /** + * operator overload to increment (prefix) + **/ + large_number &operator++() { + (*this) += 1; + return *this; + } + + /** + * operator overload to increment (postfix) + **/ + large_number &operator++(int) { + large_number tmp(_digits); + ++(*this); + return tmp; + } + + /** + * operator overload to add + **/ + large_number &operator+=(large_number n) { + // if adding with another large_number + large_number *b = reinterpret_cast(&n); + const size_t max_L = std::max(this->num_digits(), b->num_digits()); + unsigned int carry = 0; + size_t i; + for (i = 0; i < max_L || carry != 0; i++) { + if (i < b->num_digits()) carry += (*b)[i]; + if (i < this->num_digits()) carry += (*this)[i]; + if (i < this->num_digits()) + (*this)[i] = carry % 10; + else + this->add_digit(carry % 10); + carry /= 10; + } + return *this; + } + + large_number &operator+=(int n) { return (*this) += large_number(n); } + // large_number &operator+=(uint64_t n) { return (*this) += large_number(n); + // } + + /** + * operator overload to perform addition + **/ + template + friend large_number &operator+(const large_number &a, const T &b) { + large_number c = a; + c += b; + return c; + } + + /** + * assignment operator + **/ + large_number &operator=(const large_number &b) { + this->_digits = b._digits; + return *this; + } + + /** + * operator overload to increment + **/ + template + large_number &operator*=(const T n) { + static_assert(std::is_integral::value, + "Must be integer addition unsigned integer types."); + this->multiply(n); + return *this; + } + + /** + * returns i^th digit as an ASCII character + **/ + const char digit_char(size_t i) const { + return _digits[num_digits() - i - 1] + '0'; + } private: - /** - * multiply large number with another integer and - * store the result in the same large number - **/ - template - void multiply(const T n) { - static_assert(std::is_integral::value, "Can only have integer types."); - // assert(!(std::is_signed::value)); //, "Implemented only for - // unsigned integer types."); + /** + * multiply large number with another integer and + * store the result in the same large number + **/ + template + void multiply(const T n) { + static_assert(std::is_integral::value, + "Can only have integer types."); + // assert(!(std::is_signed::value)); //, "Implemented only for + // unsigned integer types."); - size_t i; - uint64_t carry = 0, temp; - for (i = 0; i < this->num_digits(); i++) { - temp = (*this)[i] * n; - temp += carry; - if (temp < 10) { - carry = 0; - } else { - carry = temp / 10; - temp = temp % 10; - } - (*this)[i] = temp; + size_t i; + uint64_t carry = 0, temp; + for (i = 0; i < this->num_digits(); i++) { + temp = (*this)[i] * n; + temp += carry; + if (temp < 10) { + carry = 0; + } else { + carry = temp / 10; + temp = temp % 10; + } + (*this)[i] = temp; + } + + while (carry != 0) { + this->add_digit(carry % 10); + carry /= 10; + } } - while (carry != 0) { - this->add_digit(carry % 10); - carry /= 10; - } - } - - std::vector _digits; /**< where individual digits are stored */ + std::vector + _digits; /**< where individual digits are stored */ }; #endif // OTHERS_LARGE_NUMBER_H_