Bigint Subtraction in C++ - c++

Here I have a bigint class that uses an array called SafeArray that I created in a different class(we couldnt use vectors) the set and get function calls are from the SafeArray class, get takes an int parameter for array position and set takes 2 int parameters(one for position and one for value) all methods in this class work fine except for my subtract and compare methods. What I really need to work is my subtraction method. Any help? Thanks
int size = 20; //just for testing, will increase later
class bigint
{
SafeArray<int> *arr;
public:
bigint()
{
arr = new SafeArray<int>;
for(int i =0;i < size; i++)
arr->set(i,0);
}
void print()
{
for(int i = 0;i <arr->get_size() ;i++)
{
cout << arr->get(i);
}
cout<<endl;
}
void assign(const bigint &A)
{
for(int i=0;i<arr->get_size();i++)
{
arr->set(i,A.arr->get(i));
}
}
void assign(int num)
{
for(int i = arr->get_size()- 1; i >= 0; i--)
{
arr->set(i,num%10);
num /=10;
}
}
void assign(string num)
{
long len = num.length();
int j=arr->get_size()-1;
for(long i=len-1;i>=0;i--)
{
arr->set(j,num[i]-48);
j--;
}
}
void add(const bigint &A)
{
int carry=0;
for(int i=size-1;i>=0;i--)
{
int result = arr->get(i)+A.arr->get(i)+carry;
arr->set(i,result%10);
carry=result/10;}
}
void subtract(const bigint &A) {
for(int i=0, borrow=0; i<size; ++i)
{ int result=((arr->get(i) - A.arr->get(i) + borrow));
if(borrow == result < 0) {
A.arr->set(i,result+=10);
} } }
void compare(const bigint & A)
{
//int comp;
//for(int i =0;i<size;i++)
if(arr->get(size-1)>A.arr->get(size-1))
cout<<0;
else
cout<<1;
}
};
int main()
{
bigint A,B,C,D;
A.assign(12345);
A.print();
cout<<endl;
C.assign("123456789000");
C.print();
cout<<endl;
B.add(C);
B.print();
//B.compare(A);
//B.subtract(A);
//B.print();
return 0;
}

I think it should look like this
void subtract(const bigint &A) {
int borrow = 0;
for(int i=size-1; i >= 0; --i)
{
int result=((arr->get(i) - A.arr->get(i) - borrow));
if(result < 0) {
arr->set(i, result + 10);
borrow = 1;
} else {
arr->set(i, result);
borrow = 0;
}
}
}
// equals A
bool equals(const bigint &A) {
for(int i=0; i < size; ++i) {
if(A.arr->get(i) != arr->get(i)) {
return false;
}
}
return true;
}
// less than A
bool lt(const bigint &A) {
for(int i=0; i < size; ++i) {
if(arr->get(i) != A.arr->get(i)) {
return arr->get(i) < A.arr->get(i);
}
}
}

Related

Can't convert memory address to value

thanks for visiting my question! Currently, when I run this code (an implementation of the Set data structure in c++), the memory address of each element in the set is printed instead of the values in the set. To help with debugging, here's my code:
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cassert>
#define PB push_back
typedef std::vector<int> vint;
class SetBase
{
public:
SetBase() {}
~SetBase() {}
void insert(int x)
{
if (!this->isInSet(x))
{
this->set.PB(x);
}
}
int size()
{
return this->set.size();
}
bool empty()
{
return this->size() == 0;
}
int operator[](int index)
{
if (index >= 0 && index < this->size())
{
return this->set[index];
}
else
{
return -1;
}
}
bool find(int target)
{
sort(this->set.begin(), this->set.end());
int low = 0, high = this->size();
while (low <= high)
{
long long mid = low + (high - low) / 2;
long long guess = this->set[mid];
if (guess == target)
return true;
else if (guess < target)
low = mid + 1;
else
high = mid - 1;
}
return false;
}
int count(int target)
{
int counter = 0;
for (int i = 0; i < this->set.size(); i++)
{
if (this->set[i] == target)
counter++;
}
return counter;
}
bool operator=(SetBase &other)
{
if (other.size() != this->size())
return false;
for (int i = 0; i < other.size(); i++)
{
if (other[i] != this->set[i])
return false;
}
return true;
}
private:
vint set;
bool isInSet(int target)
{
for (int i = 0; i < this->size(); i++)
{
if (set[i] == target)
{
return true;
}
}
return false;
}
};
class Set : public SetBase
{
public:
void set_union(Set *set1, Set *set2, Set &back_insertor)
{
for (int i = 0; i < set1->size(); i++)
{
if (this->isInSet(back_insertor, i))
{
back_insertor.insert(i);
}
}
}
void set_difference(Set set1, Set set2, Set &back_insertor)
{
// set_difference = set1 - set2
}
void set_intersection(Set set1, Set set2, Set &back_insertor)
{
// set_difference = set1 U set2
for (int i = 0; i < set1.size(); i++)
{
for (int j = 0; j < set2.size(); j++)
{
if (set1[i] == set2[j])
{
back_insertor.insert(set1[i]);
}
}
}
}
void printSet(Set *in)
{
for (int i = 0; i < in->size(); i++)
{
std::cout << &in[i] << "\n";
}
}
private:
bool isInSet(SetBase set1, int target)
{
for (int i = 0; i < set1.size(); i++)
{
if (target == set1[i])
{
return true;
}
}
return false;
}
};
int main()
{
Set *set_1 = new Set();
Set *set_2 = new Set();
Set *back = new Set();
for (int i = 1; i <= 10; i++)
set_1->insert(i);
for (int i = 1; i <= 10; i++)
set_2->insert(i);
set_2->insert(11);
set_1->set_union(set_1, set_2, *back);
set_1->printSet(set_1);
delete set_1;
delete set_2;
delete back;
}
When running the set_1->printSet(set_1); line, here's what I get:
0x7fb498c05a20
0x7fb498c05a38
0x7fb498c05a50
0x7fb498c05a68
0x7fb498c05a80
0x7fb498c05a98
0x7fb498c05ab0
0x7fb498c05ac8
0x7fb498c05ae0
0x7fb498c05af8
Even though this works, I would like to print out the values (integer) instead. Any help would be appreciated! Thanks! :)
Inside printSet(), you use &in[i] to print each element.
The & operator returns the address of the object you are referencing. So, instead of getting the value, you are getting its address. You should remove it, eg:
void printSet(Set *in)
{
for (int i = 0; i < in->size(); i++)
{
std::cout << (*in)[i] << "\n";
}
}

Memory leak without allocating any memory?

I'm working on a coding assignment for a C++ class. When I run my program I seem to be dealing with a memory leakage issue, which is weird since I am NOT explicitly allocating any memory in my code. I ran the program under gdb, and it seems as though the program crashes when running the destructor for a Deck object. I tried stepping through the code, but I when I do so I end up in a host of .h files related to vectors. Then suddenly, it stops. I tried going to a TA for some help, but they seem to be as perplexed as I am on the issue.
# include <stdlib.h>
# include <time.h>
# include <iostream>
# include <vector>
# include <stdio.h>
using namespace std;
//function signatures
float bustProbability (const int);
class Deck
{
public:
//data members
vector <int> cardArray;
vector <int> wasteCards;
//constructor
Deck();
//methods
void shuffleDeck();
void populateDeckWithCards();
void removeCopyCards();
int dealCard();
int remainingCards();
void showCards();
};
void Deck::removeCopyCards() {
for (unsigned int i = 0; i < wasteCards.size(); i++) {
bool removedCopy = false;
for (unsigned int j = 0; j < cardArray.size() && removedCopy == false; j++) {
if (cardArray[j] == wasteCards[i]) {
cardArray.erase (cardArray.begin() + j - 1);
removedCopy = true;
}
}
}
}
int Deck::dealCard() {
if (remainingCards() > 0) {
int tmp = cardArray.back();
wasteCards.push_back(tmp);
cardArray.pop_back();
return tmp;
}
else {
populateDeckWithCards();
removeCopyCards();
shuffleDeck();
//shuffle method
int tmp = cardArray.back();
cardArray.pop_back();
return tmp;
}
}
void Deck::populateDeckWithCards() {
//populate regular cards into array
for (int i = 2; i <= 10; i++) {
for (int j = 0; j < 4; j++) {
cardArray.push_back(i);
}
}
//populate J, Q, K into array
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
cardArray.push_back(10);
}
}
//populating array with Aces... treating them as special case '100'
for (int i = 0; i < 4; i++) {
cardArray.push_back(100);
}
return;
}
void Deck::showCards() {
for (unsigned int i = 0; i < cardArray.size(); i++) {
cout << cardArray[i] << endl;
}
}
Deck::Deck() {
wasteCards.clear();
cardArray.clear();
populateDeckWithCards();
shuffleDeck();
}
void Deck::shuffleDeck() {
int n = cardArray.size();
for(int a = n-1; a > 0; a--) {
int min = 0;
int max = a;
int j = min + rand() / (RAND_MAX / (max-min + 1) + 1);
int tmp = cardArray[a];
cardArray[a] = cardArray[j];
cardArray[j] = tmp;
}
return;
}
int Deck::remainingCards() {
return cardArray.size();
}
class Player {
public:
//data members
vector <int> playerHand;
//constructor
Player();
//methods
bool isBust();
int count();
void hit(Deck&);
void stand();
bool muckHand();
void showHand();
};
Player::Player() {
playerHand.clear();
}
void Player::showHand() {
for (unsigned int i = 0; i < playerHand.size(); i++) {
cout << playerHand[i] << endl;
}
return;
}
int Player::count() {
int handCount = 0;
for (unsigned int i = 0; i < playerHand.size(); i++) {
if (playerHand[i] != 100)
handCount += playerHand[i];
else {
if (playerHand[i] == 100) {
if ((handCount) > 11) {
handCount += 1;
}
else
handCount += 10;
}
}
}
return handCount;
}
bool Player::isBust() {
if (count() > 21)
return true;
else
return false;
}
void Player::hit(Deck& d) {
playerHand.push_back(d.dealCard());
}
void Player::stand() {
return;
}
bool Player::muckHand() {
playerHand.clear();
return true;
}
float bustProbability (const int threshHold) {
int threshHoldReached = 0;
Deck myDeck;
Player myPlayer;
Player dealer;
for (int i = 0; i < 10000; i++) {
myPlayer.hit(myDeck);
dealer.hit(myDeck);
myPlayer.hit(myDeck);
dealer.hit(myDeck);
while (myPlayer.count() < threshHold) {
myPlayer.hit(myDeck);
}
if (!(myPlayer.isBust())) {
++threshHoldReached;
}
myDeck.wasteCards.clear();
myPlayer.muckHand();
dealer.muckHand();
}
float bustFraction = float(threshHoldReached)/float(10000);
return bustFraction;
}
int main () {
cout << "blackjack simulation" << endl;
srand((unsigned int)time(NULL));
cout << bustProbability(19);
return 0;
}
I'm incredibly sorry for just posting my code, but I've spend 4 days on this issue, and I can't even begin to figure out what the problem is.
There is at least the line
cardArray.erase (cardArray.begin() + j - 1);
which seems to be dubious in case of j = 0

Bigint Multiplication Help C++

Here I've got a bigint calculator that uses a safearray class(not shown) to store large numbers and do arithmetic operations on them. I've got add and subtract working but when I try multiplication it compiles and runs but nothing happens. Could someone help me fix this? Thanks
int size = 100;
class bigint
{
SafeArray<int> *arr;
public:
char sign;
bigint() //initializes to zero
{
arr = new SafeArray<int>;
for(int i =0;i < size; i++)
arr->set(i,0);
}
void print() //prints numbers without zeroes in front
{
bool start_num=false;
for(int i = 0;i <arr->get_size() ;i++)
{
if(arr->get(i)!=0 && start_num==false )
{start_num=true;
cout << arr->get(i);}
else if(start_num==true)
cout<<arr->get(i);
}
cout<<endl;
}
void assign(const bigint &A) //
{
for(int i=0;i<arr->get_size();i++)
{ //Ways to initialize stuff
arr->set(i,A.arr->get(i));
}
}
void assign(int num) //
{
for(int i = arr->get_size()- 1; i >= 0; i--)
{
arr->set(i,num%10);
num /=10;
}
}
void assign(string num) //
{
long len = num.length();
int j=arr->get_size()-1;
for(long i=len-1;i>=0;i--)
{
arr->set(j,num[i]-48);
j--;
}
}
void add_pos(const bigint &A) //add big ints
{
int carry=0;
for(int i=size-1;i>=0;i--)
{
int result = arr->get(i)+A.arr->get(i)+carry;
arr->set(i,result%10);
carry=result/10;
}
}
void multiply(bigint &A)
{
bigint temp;
for(int i=0;i<size;i +=1)
{
temp.arr->set(i,arr->get(i));
arr->set(i,0);
}
int i1, i2;
for(i2=0; i2<size; i2++)
{
int borrow =0;
for(i1=0;i1+i2<size;i1++)
{
int total=temp.arr->get(i1)*A.arr->get(i2);
int totalsum=total+arr->get(i1+i2)+borrow;
arr->set(i1+i2,totalsum%10);
borrow = totalsum/10;
}
}
};
int main()
{
bigint a, b, c;
a.assign("2543281");
b.assign("3434");
a.mulitply(b);
a.print();
return 0;
}
The result of multiplication of two bigint numbers of size = 100 certainly needs more than 100 digits, perhaps 200?
For minimal modification, you may pass size as constructor argument to bigint. Ideally, bigint may use a vector so that the digit array can grow dynamically in a convenient and flexible way.
class bigint {
std::vector<int8_t> digits_; // each digit must be in 0-9 range
...
These were lil complicated so I came up with this:
InfInt InfInt::operator*(const InfInt& a) const{
InfInt final = 0;
std::string result;
InfInt* temp;
int carry;
int current;
//fast mult algorithm. the same we were taught in elementary.
for(long i=length() - 1;i >= 0; i--){
carry = 0;
result = "";
for (long j=a.length() - 1; j >= 0; j--){
current = (value[i] - '0') * (a.value[j] - '0') + carry;
result = (char)(current % 10 + '0') + result;
carry = current / 10;
}
if (carry > 0)
result = (char)(carry + '0') + result;
temp = new InfInt(result);
final += *new InfInt(temp->alignLeft(length() - i - 1));
}
final.setSign(sign ^ a.sign);
return final;
}
Hope it helps

compare two bigints c++

I've got a bigint class that uses an array called SafeArray that I created in a different class. I couldn't use vectors. The set and get function calls are from the SafeArray class. Get takes an int parameter for array position and set takes 2 int parameters (one for position and one for value). All methods in this bigint class work fine (we don't have to account for negative integers) except my compare method needs work. I want it to be able to compare two bigints and if the (const bigint and &A) number is larger than the other (cout 1) if it is smaller (cout 2) if they are the same (cout 0). Any help with this method would be greatly appreciated. Thanks
int size = 35; //will get bigger, small now just for testing
class bigint
{
SafeArray<int> *arr;
public:
bigint() //initializes to zero
{
arr = new SafeArray<int>;
for(int i =0;i < size; i++)
arr->set(i,0);
}
void print() //prints numbers without zeroes in front
{
bool start_num=false;
for(int i = 0;i <arr->get_size() ;i++)
{
if(arr->get(i)!=0 && start_num==false )
{start_num=true;
cout << arr->get(i);}
else if(start_num==true)
cout<<arr->get(i);
}
cout<<endl;
}
void assign(const bigint &A) //
{
for(int i=0;i<arr->get_size();i++)
{ //Ways to initialize stuff
arr->set(i,A.arr->get(i));
}
}
void assign(int num) //
{
for(int i = arr->get_size()- 1; i >= 0; i--)
{
arr->set(i,num%10);
num /=10;
}
}
void assign(string num) //
{
long len = num.length();
int j=arr->get_size()-1;
for(long i=len-1;i>=0;i--)
{
arr->set(j,num[i]-48);
j--;
}
}
void add(const bigint &A) //add big ints
{
int carry=0;
for(int i=size-1;i>=0;i--)
{
int result = arr->get(i)+A.arr->get(i)+carry;
arr->set(i,result%10);
carry=result/10;
}
}
void subtract(const bigint &A) //subtract big ints
{
int borrow = 0;
for(int i=size-1; i >= 0; --i)
{
int result=((arr->get(i) - A.arr->get(i) - borrow));
if(result < 0)
{
arr->set(i, result + 10);
borrow = 1;
}
else
{
arr->set(i, result);
borrow = 0;
}
}
}
//int compare(const bigint &A) //compare big ints
// {
//
// for(int i<size;i>0;i--)
// {
// if(A.arr->get(i) > arr->get(i))
// {
// return 1;
// }
// else if(A.arr->get(i) < arr->get(i))
// {
// return -1;
// }
// else
// {
// return 0;
// }
// }
//
// }
};
int main()
{
bigint a, b, c;
a.assign("12345678"); //for testing
b.assign("12345678");
//a.compare(b);
a.print();
c.assign(24691357); // 696969 is small enough to be an int.
a.add(b); // a += b;
a.subtract(c); // a -= b;
a.print();
return 0;
}
The logical problem with comparison is that you're returning two numbers as equal at the first digit that is equal.
You need instead to keep comparing next digit in that case and return 0 only if all of them are equal.

Program gives a weird runtime error

#include<iostream>
using namespace std;
class darray
{
private:
int n; // size of the array
int *a; // pointer to the 1st element
public:
darray(int size)
{
n = size;
a = new int[n];
}
~darray(){ delete[] a; }
void get_input();
int get_element(int index);
void set_element(int index, int value);
int count(){ return n; }
void print();
};
void darray::get_input()
{
for (int i = 0; i < n; i++)
{
cin >> *(a + i);
}
}
int darray::get_element(int index)
{
if (index == -1)
index = n - 1;
return a[index];
}
void darray::set_element(int index,int value)
{
a[index] = value;
}
void darray::print()
{
for (int i = 0; i < n; i++)
{
cout << a[i];
if (i < (n - 1))
cout << " ";
}
cout << endl;
}
// perform insertion sort on the array a
void insertion_sort(darray d)
{
int v = d.get_element(-1); // v is the right-most element
int e = d.count() - 1; // pos of the empty cell
// shift values greater than v to the empty cell
for (int i = (d.count() - 2); i >= 0; i--)
{
if (d.get_element(i) > v)
{
d.set_element(e,d.get_element(i));
d.print();
e = i;
}
else
{
d.set_element(e, v);
d.print();
break;
}
}
}
int main()
{
int s;
cin >> s;
darray d(s);
d.get_input();
insertion_sort(d);
system("pause");
return 0;
}
I use the darray class to make a array of size n at runtime. This class gives basic functions to handle this array.
This programs says debugging assertion failed at the end.
It gives this error after ruining the program.Other than that the program works fine. What is the reason for this error ?
You need to declare and define a copy constructor:
darray::darray(const darray& src)
{
n = src.n;
a = new int[n];
for (int i = 0; i < n; i++)
{
*(a + i) = *(src.a + i);
}
}