dcsimg
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8

Thread: Overrideing operators bigint.h

  1. #1
    Join Date
    Apr 2018
    Posts
    3

    Question Overrideing operators bigint.h

    Thank you!
    Last edited by lastHope; April 26th, 2018 at 12:32 PM.

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,412

    Re: Overrideing operators bigint.h

    [When posting code, please use code tags. Also make sure the code is formatted before posting so that the code is readable! Go Advanced, select the formatted code and click '#']

    I'll have a look at it when I have some time tomorrow (gmt).

    Cheers!
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.8.4)

  3. #3
    Join Date
    Apr 2018
    Posts
    3

    Re: Overrideing operators bigint.h

    Thank you for the edit fix. Any help is much appreciated

  4. #4
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,750

    Re: Overrideing operators bigint.h

    It would require a fair bit of reworking at this late stage, but the first thing I would recommend is to use a std::vector<int> member instead of the two member variables you have now. This would immediately simplify memory management, allowing you to ditch things like explicitly defining the copy constructor, destructor, and copy assignment operator.

    One idea that tends to crop up for this kind of classes is that you might want to consider defining operator+= as a member function, then define operator+ as a non-member non-friend function that invokes the member operator+= to do its job, e.g.,
    Code:
    BigInteger operator+(BigInteger x, const BigInteger& y)
    {
        return x += y;
    }
    This can be an advantage in that it will then allow expressions like 123 + some_big_integer, with an appropriate non-explicit constructor, whereas a member operator+ will allow some_big_integer + 123 but not the former. Unfortunately, it looks like your relevant constructor allocates size rather than converts the integer argument to a BigInteger, so this would be a Bad Thing, and in fact it means that that constructor should be declared explicit, otherwise something like this:
    Code:
    BigInteger x = 123;
    would result in a BigInteger of value 0 but with a max digits of 123, whereas people would probably expect x to be a BigInteger of value 123 with the default max digits.

    Likewise, even before delving into the nitty gritty of operator== (which will likely involve comparing the individual digits of the BigInteger objects, no?) you can already implement operator!= as a non-member non-friend function in terms of the yet-to-be-implemented operator==, i.e., taking advantage of the fact that a != b is equivalent to !(a == b). (You could implement operator< alone and then use it to implement all the other relational operators, but in these cases it is often more efficient to treat operator== separately and use it to implement operator!=, and then implement operator< and use it to implement operator<=, operator>, and operator>= with little extra work.)

    The output operator with ostream seems fairly trivial: wouldn't you just loop over the digits and print them?
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  5. #5
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,412

    Re: Overrideing operators bigint.h

    I agree with laserlight's comments in post #4.

    Is this a homework exercise? What compiler are you using as

    Code:
    #include <iostream.h>
    is not standard c++. It should be

    Code:
    #include <iostream>
    and

    Code:
    cout << "Attempt to read illegal character into a BigInteger!" << endl;
    shouldn't compile as cout is defined in the std namespace, so without a using... statement, this should be

    Code:
    std::cout << "Attempt to read illegal character into a BigInteger!" << std::endl;
    Without changing to using a vector, the code in post #1 can be simplified. When a function ends, the destructor of its class variables are called - which for BigInteger releases the allocated memory. So for say operator=, if the copy constructor is called to create a new instance, then the contents of that new instance are swapped with the contents of the current instance, then the assignment will have been done and when the function ends, the memory allocated to the new instance - which was the already allocated memory of the current instance - will be freed by the destructor. Simples!!

    [Sample example code to follow]
    Last edited by 2kaud; April 26th, 2018 at 08:42 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.8.4)

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,412

    Re: Overrideing operators bigint.h

    I've simplified the code from post #1 and added the swap() method, the operator== (and !=) and also a constructor that takes string as a number. Consider

    Code:
    #include <iostream>
    #include <algorithm>
    #include <cstdlib>
    #include <sstream>
    #include <string>
    using namespace std;
    
    const int mindigits = 20;
    
    class BigInteger
    {
    public:
    	explicit BigInteger(int md = mindigits); // specify-size constructor
    	BigInteger(const string& sbi);
    	~BigInteger(); // destructor
    	BigInteger(const BigInteger&); // copy constructor
    
    	void swap(BigInteger&);
    
    	BigInteger& operator= (const BigInteger&);
    	BigInteger& operator= (int);
    
    	BigInteger operator+ (const BigInteger&) const;
    	BigInteger operator+ (int) const;
    	BigInteger operator* (int) const;
    	//BigInteger operator/ (const int&) const;
    	//int operator% (const int&) const;
    
    	bool operator==(const BigInteger&) const;
    	bool operator!=(const BigInteger&) const;
    
    	friend ostream& operator<<(ostream&, const BigInteger&);
    	friend istream& operator>>(istream&, BigInteger&);
    
    private:
    	int *BigArray = nullptr;
    	int Size = 0;
    };
    
    BigInteger::BigInteger(int MaxDigits)
    {
    	Size = std::max(mindigits, MaxDigits);
    	BigArray = new int[Size];
    	memset(BigArray, 0, sizeof(int) * Size);
    }
    
    BigInteger::BigInteger(const string& bsi) : BigInteger(bsi.size())
    {
    	int e = Size - bsi.size();
    
    	for (auto i = bsi.begin(); (i != bsi.end()) && isdigit(*i); ++i)
    		BigArray[e++] = *i - '0';
    }
    
    BigInteger::~BigInteger()
    {
    	delete [] BigArray;
    }
    
    BigInteger::BigInteger(const BigInteger& B)
    {
    	BigArray = new int[B.Size];
    	Size = B.Size;
    	memcpy(BigArray, B.BigArray, sizeof(int) * Size);
    }
    
    void BigInteger::swap(BigInteger& B)
    {
    	std::swap(Size, B.Size);
    	std::swap(BigArray, B.BigArray);
    }
    
    BigInteger& BigInteger::operator=(const BigInteger& B)
    {
    	const int msz = std::max(Size, B.Size);
    	BigInteger temp(msz);
    
    	memcpy(temp.BigArray + (msz - B.Size), B.BigArray, sizeof(int) * B.Size);
    	swap(temp);
    
    	return *this;
    }
    
    BigInteger& BigInteger::operator=(int x)
    {
    	for (int i = Size - 1; i >= 0; --i, x /= 10)
    		BigArray[i] = x % 10;
    
    	return *this;
    }
    
    bool BigInteger::operator==(const BigInteger& B) const
    {
    	int a = 0, b = 0;
    
    	for (; a < Size && BigArray[a] == 0; ++a);
    	for (; b < B.Size && B.BigArray[b] == 0; ++b);
    
    	return ((Size - a) == (B.Size - b)) && (memcmp(B.BigArray + b, BigArray + a, Size - a) == 0);
    }
    
    bool BigInteger::operator!=(const BigInteger& B) const
    {
    	return !operator==(B);
    }
    
    BigInteger BigInteger::operator+(const BigInteger& C) const
    {
    	const int maxs = std::max(Size, C.Size) + 1;
    	BigInteger First(maxs), Second(maxs);
    
    	First = *this;
    	Second = C;
    
    	int carry = 0;
    
    	for (int i = maxs - 1; i >= 0; --i)
    	{
    		const int x = First.BigArray[i] + Second.BigArray[i] + carry;
    		First.BigArray[i] = x % 10;
    		carry = x / 10;
    	}
    
    	if (carry != 0)
    	{
    		cout << "Addition Overflow of Big Integers!" << endl;
    		exit(-1);
    	}
    
    	return First;
    }
    
    BigInteger BigInteger::operator+(int n) const
    {
    	BigInteger First(Size);
    
    	First = n;
    	return operator+(First);
    }
    
    BigInteger BigInteger::operator*(int n) const
    {
    	BigInteger CopyOfBig(*this);
    	const int FrontPart = n / 10, LastDigit = n % 10;
    	int carry = 0;
    
    	for (int i = Size - 1; i >= 0; --i)
    	{
    		const int x = LastDigit * CopyOfBig.BigArray[i] + carry % 10;
    		carry = FrontPart * CopyOfBig.BigArray[i] + x / 10 + carry / 10;
    		CopyOfBig.BigArray[i] = x % 10;
    	}
    
    	if (carry != 0)
    	{
    		cout << "Multiplication Overflow of a Big Integer with an int!" << endl;
    		exit(-1);
    	}
    
    	return CopyOfBig;
    }
    
    istream& operator>>(istream& InFile, BigInteger& B)
    {
    	string si;
    
    	InFile >> si;
    
    	for (const auto& s : si)
    		if (!isdigit(s)) {
    			InFile.setstate(ios::failbit);
    			return InFile;
    		}
    
    	BigInteger t(si);
    
    	B.swap(t);
    	return InFile;
    }
    
    ostream& operator<<(ostream& os, const BigInteger& B)
    {
    	int e = 0;
    
    	for (; (e < B.Size) && (B.BigArray[e] == 0); ++e);
    	for (; e < B.Size; os << B.BigArray[e++]);
    
    	return os;
    }
    
    int main()
    {
    	istringstream iss("123");
    
    	BigInteger bi1;
    	BigInteger bi2;
    
    	iss >>  bi1;
    	cout << "bi1 " << bi1 << endl;
    
    	bi2 = 456;
    	cout << "bi2 " << bi2 << endl;
    
    	bi1 = bi2;
    	cout << "bi1 " << bi1 << endl;
    
    	cout << "bi1 == bi2 " << (bi1 == bi2) << endl;
    	cout << "bi1 + bi2 " << bi1 + bi2 << endl;
    	cout << "bi1 + 234 " << bi1 + 234 << endl;
    	cout << "bi1 * 567 " << bi1 * 567 << endl;
    }
    giving the expected test output of

    Code:
    bi1 123
    bi2 456
    bi1 456
    bi1 == bi2 1
    bi1 + bi2 912
    bi1 + 234 690
    bi1 * 567 258552
    I suggest that you implement += and -= and then re-code + (and -) in terms of += and -= as per laserlight's post #4.
    Last edited by 2kaud; April 26th, 2018 at 11:54 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.8.4)

  7. #7
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    6,412

    Re: Overrideing operators bigint.h

    There are 5 in total. /,%,==,!=,ostream
    ==, != and ostream are as post #6.

    For % and /, have a look at https://en.wikipedia.org/wiki/Division_algorithm for some methods.

    For info as to multiply 2 BigIntegers, have a look at https://en.wikipedia.org/wiki/Multiplication_algorithm
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++17 Compiler: Microsoft VS2017 (15.8.4)

  8. #8
    Join Date
    Apr 2018
    Posts
    3

    Re: Overrideing operators bigint.h

    Thank you for all the help!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)