Virtual function doesnt work correctly - c++

I need to write a program using virtual function of addition and inheritance.
i wrote this 3 classes, but my virtual function doesnt display the result.
it should write the summ of decimal de("10004") and decimal deci("12"); but it just displays Array->
how can i possibly fix this?
#include <string>
#include <iostream>
#include <cassert>
using namespace std;
int rev(int);
class Array
{
private:
string arr[100];
size_t size;
string str;
public:
Array();
Array(string s)
{
str = s;
cout << str << endl;
}
/*{
cin >> size;
for (int i = size - 1; i >= 0; i--)
{
arr[i] = '0';
cout << arr[i];
}
cout << endl;
}*/
string& operator[] (const int index);
Array operator +(Array ar)
{
int x = stoi(str);
int y = stoi(ar.str);
int d = x + y;
string s = to_string(d);
return s;
}
virtual void plus( Array *b)
{
cout << "Array -> " << str + b->str << endl;
}
};
string& Array::operator[] (const int index)
{
assert(index >= 0 && index < size);
return arr[index];
}
class decimal : public Array
{
private:
unsigned char dec[100];
size_t size;
public:
decimal() : size{ 0 } {}
decimal(const char* get)
{
size = strlen(get);
for (int i = size - 1; i >= 0; i--, get++)
{
dec[i] = *get;
cout << dec[i];
}
cout << endl;
}
void plus(decimal* b);
friend decimal operator + (decimal const &, decimal const &);
friend decimal operator - (decimal const &, decimal const &);
friend decimal operator * (decimal const &, decimal const &);
friend decimal operator / (decimal const &, decimal const &);
friend decimal operator % (decimal const &, decimal const &);
};
decimal operator + (decimal const &a, decimal const &b)
{
int x = atoi((char *)a.dec);
int y = atoi((char *)b.dec);
int d = rev(x) + rev(y);
string s = to_string(d);
return decimal(s.c_str());
}
decimal operator - (decimal const &a, decimal const &b)
{
int x = atoi((char *)a.dec);
int y = atoi((char *)b.dec);
int d = rev(x) - rev(y);
string s = to_string(d);
return decimal(s.c_str());
}
decimal operator * (decimal const &a, decimal const &b)
{
int x = atoi((char *)a.dec);
int y = atoi((char *)b.dec);
int d = rev(x) * rev(y);
string s = to_string(d);
return decimal(s.c_str());
}
decimal operator / (decimal const &a, decimal const &b)
{
int x = atoi((char *)a.dec);
int y = atoi((char *)b.dec);
int d = rev(x) / rev(y);
string s = to_string(d);
return decimal(s.c_str());
}
decimal operator % (decimal const &a, decimal const &b)
{
int x = atoi((char *)a.dec);
int y = atoi((char *)b.dec);
int d = rev(x) % rev(y);
string s = to_string(d);
return decimal(s.c_str());
}
void decimal::plus( decimal* b)
{
cout << "Array -> " << atoi((char*)dec) + atoi((char *)b->dec) << endl;
}
int rev(int n)
{
int r = 0, remainder;
while (n != 0)
{
remainder = n % 10;
r = r * 10 + remainder;
n /= 10;
}
return r;
}
class BitString : public Array
{
char *string;
public:
BitString() = default;
BitString(char *str)
{
string = new char[strlen(str) + 1]; strcpy_s(string, strlen(str) + 1, str);
}
void operator ~()
{
for (int i = 0; i<strlen(string); i++)
string[i] == '1' ? string[i] = '0' : string[i] = '1';
}
void operator &(BitString a)
{
if (strlen(string) != strlen(a.string))
cout << "Different lengths" << endl;
else
{
for (int i = 0; i<strlen(a.string); i++)
if (string[i] == '1' && a.string[i] == '1')
string[i] = '1';
else
string[i] = '0';
}
}
void operator +(BitString a)
{
if (strlen(string) != strlen(a.string))
cout << "Different lengths" << endl;
else
{
for (int i = 0; i<strlen(a.string); i++)
if (string[i] == '1' || a.string[i] == '1')
string[i] = '1';
else
string[i] = '0';
}
for (int i = 0; i < strlen(string); i++)
cout << string[i];
cout << endl;
}
void operator ^(BitString a)
{
if (strlen(string) != strlen(a.string))
cout << "Different lengths";
else
{
for (int i = 0; i<strlen(a.string); i++)
if ((string[i] == '1' && a.string[i] == '0') || (string[i] == '0' && a.string[i] == '1'))
string[i] = '1';
else
string[i] = '0';
}
}
void Show()
{
cout << string << endl;
}
void plus(BitString *b)
{
cout << "bitstring -> " << atoi(string) + atoi(b->string) << endl;
}
};
int main()
{
int a;
char str[80];
Array *arr;
Array *arr1;
BitString obj("1010101");
BitString obj1("1110001");
decimal de("10004");
decimal deci("12");
arr = &de;
arr1 = &deci;
arr->plus(arr1);
system("Pause");
}
EDIT:
#include <string>
#include <iostream>
#include <cassert>
using namespace std;
int rev(int);
class Array
{
public:
string arr[100];
size_t size;
string str;
public:
Array() { };
Array(string s)
{
str = s;
cout << str << endl;
}
string& operator[] (const int index);
Array operator +(Array ar)
{
int x = stoi(str);
int y = stoi(ar.str);
int d = x + y;
string s = to_string(d);
return s;
}
virtual void plus(Array *b)
{
cout << "Array -> " << str + b->str << endl;
}
};
string& Array::operator[] (const int index)
{
assert(index >= 0 && index < size);
return arr[index];
}
class decimal : public Array
{
private:
unsigned char dec[100];
size_t size;
public:
decimal() : size{ 0 } {}
decimal(const char* get)
{
size = strlen(get);
for (int i = size - 1; i >= 0; i--, get++)
{
dec[i] = *get;
cout << dec[i];
}
cout << endl;
}
void plus(Array* b);
friend decimal operator + (decimal const &, decimal const &);
friend decimal operator - (decimal const &, decimal const &);
friend decimal operator * (decimal const &, decimal const &);
friend decimal operator / (decimal const &, decimal const &);
friend decimal operator % (decimal const &, decimal const &);
};
decimal operator + (decimal const &a, decimal const &b)
{
int x = atoi((char *)a.dec);
int y = atoi((char *)b.dec);
int d = rev(x) + rev(y);
string s = to_string(d);
return decimal(s.c_str());
}
decimal operator - (decimal const &a, decimal const &b)
{
int x = atoi((char *)a.dec);
int y = atoi((char *)b.dec);
int d = rev(x) - rev(y);
string s = to_string(d);
return decimal(s.c_str());
}
decimal operator * (decimal const &a, decimal const &b)
{
int x = atoi((char *)a.dec);
int y = atoi((char *)b.dec);
int d = rev(x) * rev(y);
string s = to_string(d);
return decimal(s.c_str());
}
decimal operator / (decimal const &a, decimal const &b)
{
int x = atoi((char *)a.dec);
int y = atoi((char *)b.dec);
int d = rev(x) / rev(y);
string s = to_string(d);
return decimal(s.c_str());
}
decimal operator % (decimal const &a, decimal const &b)
{
int x = atoi((char *)a.dec);
int y = atoi((char *)b.dec);
int d = rev(x) % rev(y);
string s = to_string(d);
return decimal(s.c_str());
}
void decimal::plus(Array* b)
{
cout << "Array -> " << atoi((char*)dec) + stoi(b->str) << endl;
}
int rev(int n)
{
int r = 0, remainder;
while (n != 0)
{
remainder = n % 10;
r = r * 10 + remainder;
n /= 10;
}
return r;
}
class BitString : public Array
{
char *string;
public:
BitString() = default;
BitString(char *str)
{
string = new char[strlen(str) + 1]; strcpy_s(string, strlen(str) + 1, str);
}
void operator ~()
{
for (int i = 0; i<strlen(string); i++)
string[i] == '1' ? string[i] = '0' : string[i] = '1';
}
void operator &(BitString a)
{
if (strlen(string) != strlen(a.string))
cout << "Different lengths" << endl;
else
{
for (int i = 0; i<strlen(a.string); i++)
if (string[i] == '1' && a.string[i] == '1')
string[i] = '1';
else
string[i] = '0';
}
}
void operator +(BitString a)
{
if (strlen(string) != strlen(a.string))
cout << "Different lengths" << endl;
else
{
for (int i = 0; i<strlen(a.string); i++)
if (string[i] == '1' || a.string[i] == '1')
string[i] = '1';
else
string[i] = '0';
}
for (int i = 0; i < strlen(string); i++)
cout << string[i];
cout << endl;
}
void operator ^(BitString a)
{
if (strlen(string) != strlen(a.string))
cout << "Different lengths";
else
{
for (int i = 0; i<strlen(a.string); i++)
if ((string[i] == '1' && a.string[i] == '0') || (string[i] == '0' && a.string[i] == '1'))
string[i] = '1';
else
string[i] = '0';
}
}
void Show()
{
cout << string << endl;
}
void plus(Array *b)
{
cout << "bitstring -> " << atoi(string) + stoi(b->str) << endl;
}
};
int main()
{
int a;
char str[80];
Array *arr;
Array *arr1;
BitString obj("1010101");
BitString obj1("1110001");
decimal de("10004");
decimal deci("12");
arr = &de;
arr1 = &deci;
arr->plus(arr1);
arr = &obj;
arr1 = &obj1;
arr->plus(arr1);
system("Pause");
}

Try to replace variable named string in BitString. It is defined type from <string> library in namespace std and you use it with using namespace std; There is a confusion with naming. For example I renamed string to stringMine in this example:
class BitString : public Array
{
char *stringMine;
public:
BitString() = default;
BitString(char *str)
{
stringMine = new char[strlen(str) + 1]; strcpy_s(stringMine, strlen(str) + 1, str);
}
void operator ~()
{
for (int i = 0; i<strlen(stringMine); i++)
stringMine[i] == '1' ? stringMine[i] = '0' : stringMine[i] = '1';
}
void operator &(BitString a)
{
if (strlen(stringMine) != strlen(a.stringMine))
cout << "Different lengths" << endl;
else
{
for (int i = 0; i<strlen(a.stringMine); i++)
if (stringMine[i] == '1' && a.stringMine[i] == '1')
stringMine[i] = '1';
else
stringMine[i] = '0';
}
}
void operator +(BitString a)
{
if (strlen(stringMine) != strlen(a.stringMine))
cout << "Different lengths" << endl;
else
{
for (int i = 0; i<strlen(a.stringMine); i++)
if (stringMine[i] == '1' || a.stringMine[i] == '1')
stringMine[i] = '1';
else
stringMine[i] = '0';
}
for (int i = 0; i < strlen(stringMine); i++)
cout << stringMine[i];
cout << endl;
}
void operator ^(BitString a)
{
if (strlen(stringMine) != strlen(a.stringMine))
cout << "Different lengths";
else
{
for (int i = 0; i<strlen(a.stringMine); i++)
if ((stringMine[i] == '1' && a.stringMine[i] == '0') || (stringMine[i] == '0' && a.stringMine[i] == '1'))
stringMine[i] = '1';
else
stringMine[i] = '0';
}
}
void Show()
{
cout << stringMine << endl;
}
void plus(BitString *b)
{
cout << "bitstring -> " << atoi(stringMine) + atoi(b->stringMine) << endl;
}
};
Also you need to override void plus(Array *b) correctly
void decimal::plus( decimal* b); doesn't override it is a new function, it must be
void decimal::plus( Array* b)
to override. Or for good syntax:
virtual void decimal::plus( Array* b) override
Also about BitString method, right way to override is to:
virtual void plus(Array *b) override
{
cout << "bitstring -> " << atoi(stringMine) + atoi(b->stringMine) << endl;
}
But after all you will be need to declare two variables in base class to fix compile errors:
class Array
{
public:
char *stringMine;
unsigned char dec[100];
You call these variables in derived classes from base class.

Your parameter types are different, you are not overriding in derived classes but simply hiding the base class definition.
It should say
class decimal : public Array
{
public:
void plus(Array* b);
};
class BitString : public Array
{
public:
void plus(Array* b);
};

Related

implement copy constructor c++ Polynomial and Rational

I need some help to understand how to implement the constructor in the Rational class.
I try to send the numerator(p1) and denominator(p2) by reference to the rational class however it start both of them to "0" and not copy them.
the idea is to create rational that contain two Polynomial (numerator and denominator) and print them.
I didn't add all the code just what I think is relevant.
class Polynomial
{
private:
double *varibles;
static int degree;
public:
Polynomial(double * var = NULL, static int deg = NULL);
Polynomial(static int deg );
};
class Rational
{
private:
Polynomial numerator;
Polynomial denominator;
public:
Rational(const Polynomial& p1 , const Polynomial & p2 );
cpp file
Rational::Rational(const Polynomial& p1 , const Polynomial & p2 )
{
this->numerator = p1;
this->denominator = p2;
}
Polynomial::Polynomial(double * var, static int deg) {
if (deg < (sizeof(var) / sizeof(double)))
var = (double*)realloc(var, deg * sizeof(double));
this -> degree = deg;
this -> varibles = var;
}
Polynomial::Polynomial(static int deg) {
this->degree = deg;
this->varibles = (double*)calloc(deg, sizeof(double));
}
void Polynomial::setCoeff(int index, double num) {
if (!this->degree)
Polynomial(index);
this->varibles[index] = num;
}
void Polynomial::SetPolynomial(Polynomial& p) {
int size = p.degree;
int i;
for (i = 0; i < size; i++) {
cout << "Enter Number for X^ " << i+1 << " varibles" << endl;
cin >> p.varibles[i];
}
}
double Polynomial::getDegree(bool what) const {
if (what == false)
return this->degree;
else
return 0;
}
double Polynomial::getCoeff(int index) const {
return this->varibles[index];
}
int Polynomial::getMaxDegree() {
return degree;
}
void Polynomial::print() {
int size = this->degree ; // -1 ?
int i;
if (!this->degree)
cout << "Polynomial = 0";
else {
while (this->varibles[size] == 0)
size--;
if (size < 1 && this->varibles[0] == 0) {
cout << "Polynomial = 0";
}
else {
for (i = 0; i < size; i++) {
if (i == 0)
cout << this->varibles[i] << "+";
else
cout << this->varibles[i] << "X^" << i << "+";
}
cout << this->varibles[i] << "X^" << i ;
}
}
cout << endl;
}
main / test
void testRational() {
Rational r1;
r1.print();
double c[] = { 0,2,2,3,4,5 };
Polynomial p1(c, 5);
p1.print();
c[0] = 1.2;
Polynomial p2(c, 3);
Rational r2(p1, p2);
cout << "test8" << endl;
r2.print();

problem combining bignum library with bubble sort

From this post: Compare two string as numeric value
I did not get a result.
Please open this post so that someone can answer my question.
I wrote this library (pr.h):
#include <iostream>
#include <string>
#include <bits/stdc++.h>
using namespace std;
class BigNum {
private:
string doSum(string a, string b)
{
if(a.size() < b.size())
swap(a, b);
int j = a.size()-1;
for(int i=b.size()-1; i>=0; i--, j--)
a[j]+=(b[i]-'0');
for(int i=a.size()-1; i>0; i--)
{
if(a[i] > '9')
{
int d = a[i]-'0';
a[i-1] = ((a[i-1]-'0') + d/10) + '0';
a[i] = (d%10)+'0';
}
}
if(a[0] > '9')
{
string k;
k+=a[0];
a[0] = ((a[0]-'0')%10)+'0';
k[0] = ((k[0]-'0')/10)+'0';
a = k+a;
}
return a;
}
bool isSmaller(string str1, string str2)
{
int n1 = str1.length(), n2 = str2.length();
if (n1 < n2)
return true;
if (n2 < n1)
return false;
for (int i = 0; i < n1; i++) {
if (str1[i] < str2[i])
return true;
else if (str1[i] > str2[i])
return false;
}
return false;
}
string findDiff(string str1, string str2)
{
if (isSmaller(str1, str2))
swap(str1, str2);
string str = "";
int n1 = str1.length(), n2 = str2.length();
int diff = n1 - n2;
int carry = 0;
for (int i = n2 - 1; i >= 0; i--) {
int sub = ((str1[i + diff] - '0') - (str2[i] - '0')
- carry);
if (sub < 0) {
sub = sub + 10;
carry = 1;
}
else
carry = 0;
str.push_back(sub + '0');
}
for (int i = n1 - n2 - 1; i >= 0; i--) {
if (str1[i] == '0' && carry) {
str.push_back('9');
continue;
}
int sub = ((str1[i] - '0') - carry);
if (i > 0 || sub > 0)
str.push_back(sub + '0');
carry = 0;
}
reverse(str.begin(), str.end());
return str;
}
public:
string num;
BigNum () {
num = "";
}
BigNum (string tmp) {
num = tmp;
}
string operator +(BigNum a1) {
return doSum(this->num,a1.num);
}
void operator = (BigNum * a1) {
this-> num = a1-> num;
}
void operator = (string tmp) {
this-> num = tmp;
}
bool operator > (BigNum a1) {
if (this->num>a1.num){
return true;
}
else{
return false;
}
}
bool operator < (BigNum a1) {
if (this->num<a1.num){
return true;
}
else{
return false;
}
}
string operator - (BigNum a1) {
return findDiff(this->num, a1.num);
}
friend ostream &operator<<( ostream &output, const BigNum &D ) {
output << D.num;
return output;
}
friend istream &operator>>( istream &input, BigNum &D ) {
input >> D.num;
return input;
}
string operator -=(string tmp){
this->num=findDiff(this->num, tmp);
return this->num;
}
};
And this code:
// C++ program for implementation of Bubble sort
#include "pr.h"
#include <bits/stdc++.h>
using namespace std;
void swap(BigNum *xp, BigNum *yp)
{
BigNum temp = *xp;
*xp = *yp;
*yp = temp;
}
// A function to implement bubble sort
void bubbleSort(BigNum arr[], int n)
{
int i, j;
for (i = 0; i < n-1; i++)
// Last i elements are already in place
for (j = 0; j < n-i-1; j++)
if (arr[j] > arr[j+1])
swap(&arr[j], &arr[j+1]);
}
/* Function to print an array */
void printArray(BigNum arr[], int size)
{
int i;
for (i = 0; i < size; i++)
cout << arr[i] << " ";
cout << endl;
}
// Driver code
int main()
{
BigNum arr[5];
arr[0]="5";
arr[1]="5";
arr[2]="1";
arr[3]="3";
arr[4]="8";
int n = sizeof(arr)/sizeof(arr[0]);
bubbleSort(arr, n);
cout<<"Sorted array: \n";
printArray(arr, n);
return 0;
}
My problem is that this program can only sort 1-digit numbers and gives errors for multi-digit numbers
Example:
This code:
BigNum arr [5];
arr [0] = "100";
arr [1] = "5";
arr [2] = "1";
arr [3] = "3";
arr [4] = "8";
int n = sizeof (arr) / sizeof (arr [0]);
bubbleSort (arr, n);
cout << "Sorted array: \ n";
printArray (arr, n);
Prints this value:
1 100 3 5 8
bool operator < (BigNum a1) is calling std::string:: operator<, thus you getting lexicographical order. The operators < and > should call isSmaller.
bool operator > (const BigNum& a1) const {
return !isSmaller(a1) && num != a1.num;
}
bool operator < (const BigNum& a1) const {
return isSmaller(a1);
}
Do not use constructions
if (smth) return true else return false. You already get true or false in smth, use return smth.

User input has a different output from assigned-value input though both of them have the same value

I am building a custom string class. However, the user inputs give different output from the assigned-value one. For example:
With the assigned values:
#include"custom_string.h"
int main() {
string a = "Hello";
string b = "World";
string c = a + b;
std::cout << "C string is: " << c << std::endl;
std::cout << "Length of C string is: " << c.length() << std::endl;
system("pause");
return 1;
}
Then the output would be:
C string is: HelloWorld
Length of C string is: 10
In user input case:
#include"custom_string.h"
int main() {
string a;
string b;
string c = a + b;
std::cout << "Input a string: " << std::endl;
std::cin >> a;
std::cout << "Input b string: " << std::endl;
std::cin >> b;
std::cout << "C string is: " << c << std::endl;
std::cout << "Length of C string is: " << c.length() << std::endl;
system("pause");
return 0;
}
Then the output would be:
Input a string:
Hello
Input b string:
World
C string is:
Length of C string is: 0
Here is the code source of "custom_string.h":
#ifndef _STRING
#define _STRING
#include<iostream>
#include<cstring>
#define MAX 99999
class string {
private:
char* s = nullptr; //Member of custom string
unsigned int size = 0; // length of string (including '\0')
public:
string();
~string() { delete s; };
string(char* );
string(const char* );
string(const string&);
friend std::istream& operator >> (std::istream&, string&);
friend std::ostream& operator << (std::ostream&, string&);
friend string operator +(string, string);
string& operator = (const string&);
string& operator = (const char&);
unsigned int length();
char* output() const{
return s;
}
};
#endif
string::string() :s{ nullptr } {
size = 1;
s = new char[size];
s[0] = '\0';
}
string::string(char* source) {
if (source == nullptr) {
size = 1;
s = new char[size];
s[0] = '\0';
}
else {
size_t i = 0;
while (source[i] != '\0') { //To remove NULL/redundant elements of source array from istream assignment
i++;
}
size = i + 1;
s = new char[size];
s[size - 1] = '\0';
for (size_t k = 0; k < size - 1; k++) {
s[k] = source[k];
}
}
}
string::string(const char* source) {
if (source == nullptr) {
size = 1;
s = new char[size];
s[0] = '\0';
}
else {
size = strlen(source) + 1;
s = new char[size];
s[size - 1] = '\0';
for (size_t k = 0; k < (size - 1); k++) {
s[k] = source[k];
}
}
}
string::string(const string& t) {
size = t.size;
s = new char[size];
for (size_t k = 0; k < size; k++) {
s[k] = t.s[k];
}
}
string& string::operator=(const string& source) {
if (source.s == s) {
return *this;
}
else {
delete[] s;
size = source.size;
s = new char[size];
for (size_t k = 0; k < size; k++) {
s[k] = source.s[k];
}
return *this;
}
}
string& string::operator=(const char&source) {
const char* t = &source;
if (t == nullptr) {
size = 1;
s = new char[size];
s[0] = '\0';
}
else {
size = strlen(t) + 1;
s = new char[size];
s[size - 1] = '\0';
for (size_t k = 0; k < (size - 1); k++) {
s[k] = t[k];
}
}
return* this;
}
string operator +(string a, string b) {
if (a.s == nullptr ) { return b; }
if (b.s == nullptr ) { return a; }
string t;
size_t k = 0;
size_t l = 0;
t.size = (a.size + b.size) - 1;
t.s = new char[t.size];
while (a.s[k] != '\0' && k < a.size && k < t.size) {
t.s[k] = a.s[k];
k++;
}
while (k < t.size && l < b.size) {
t.s[k] = b.s[l];
k++;
l++;
}
return t;
}
std::istream& operator >> (std::istream& is, string& source) {
char* t = new char[MAX];
is >> t;
source = string{ t };
delete[] t;
return is;
}
std::ostream& operator << (std::ostream& os, string& source) {
os << source.output();
return os;
}
unsigned int string::length() {
return (size - 1); //Ignore the '\0' character
}
I do not know what makes the difference between to cases. Maybe I have missed some necessary commands.
Edit: I have known assigning c after input a and b will solve the problem. However, I don't want to do so because I want to separate assigning part and complying part in order to have neat code. Is there any way to fix error without assigning c after input a and b?
#include"custom_string.h"
int main() {
string a;
string b;
std::cout << "Input a string: " << std::endl;
std::cin >> a;
std::cout << "Input b string: " << std::endl;
std::cin >> b;
string c = a + b;
std::cout << "C string is: " << c << std::endl;
std::cout << "Length of C string is: " << c.length() << std::endl;
system("pause");
return 0;
}

Implement the Long Integer class. Provide the ability to perform arithmetic operations with instances of the class

I have an implementation of the Long Integer class, which should provide the ability to perform arithmetic operations with instances of the class.
It works in 95% of situations, but sometimes it shows wrong results.
The screen with wrong answers is located below the code.
HugeInt.h:
#ifndef _HUGEINGH
#define _HUGEINGH
#include <iostream>
#include <list>
#include <string>
#include <math.h>
using namespace std;
class HugeInt {
private:
char* listNumber;
int maxLength, length;
bool plus;
void expansion_size_length();
void updatingLength();
void set_listNumber(int position, char num);
char get_listNumber(int position);
char symbol_in_numeral(char symbol);
char numeral_in_symbol(char numeral);
public:
string toString();
void setNumber(string str);
HugeInt operator-(HugeInt HugeInt);
HugeInt operator+(HugeInt HugeInt);
HugeInt operator*(HugeInt HugeInt);
HugeInt(string str);
HugeInt();
HugeInt(const HugeInt &lg);
~HugeInt();
};
#endif
Hugeint.cpp:
#include "stdafx.h"
#include "HugeInt.h"
void HugeInt::expansion_size_length() {
char* tmp = new char[maxLength * 2];
for (int i = 0; i < maxLength; i++) {
tmp[i] = listNumber[i];
}
delete[] listNumber;
listNumber = tmp;
maxLength *= 2;
}
void HugeInt::updatingLength() {
while (length > 1) {
int tmp = listNumber[length - 1];
if (listNumber[length - 1] == 0) {
length--;
}
else {
return;
}
}
}
void HugeInt::set_listNumber(int position, char num) {
if (position < maxLength) {
listNumber[position] = num;
if (position >= length)
length = position + 1;
}
else {
while (position > maxLength)
expansion_size_length();
length = position + 1;
}
}
char HugeInt::get_listNumber(int position) {
if (position < length) {
return listNumber[position];
}
return 0;
}
char HugeInt::symbol_in_numeral(char symbol) {
return symbol - '0';
}
char HugeInt::numeral_in_symbol(char numeral) {
return numeral + '0';
}
string HugeInt::toString() {
string str = string();
if (!plus)
str.insert(str.size(), 1, '-');
for (int i = length - 1; i >= 0; i--) {
str.insert(str.size(), 1, numeral_in_symbol(listNumber[i] / 10));
str.insert(str.size(), 1, numeral_in_symbol(listNumber[i] % 10));
}
return str;
}
void HugeInt::setNumber(string str) {
//plus = true;
//maxLength = 10;
//listNumber = new char[maxLength];
length = 0; // дело в этом
delete[] listNumber;
listNumber = new char[str.length() + 1];
maxLength = str.length() + 1;
for (int i = length; i < maxLength; i++)
listNumber[i] = 0;
length = maxLength;
if (str.size() != 0) {
int k = 0;
if (str[0] == '-') {
plus = false;
for (int i = str.size() - 1; i > 0; i -= 2) {
if (i - 1 > 0)
listNumber[k] = symbol_in_numeral(str[i]) + symbol_in_numeral(str[i - 1]) * 10;
else listNumber[k] = symbol_in_numeral(str[i]);
k++;
}
}
else if (str[0] == '+') {
plus = true;
for (int i = str.size() - 1; i > 0; i -= 2) {
if (i - 1 > 0)
listNumber[k] = symbol_in_numeral(str[i]) + symbol_in_numeral(str[i - 1]) * 10;
else listNumber[k] = symbol_in_numeral(str[i]);
k++;
}
}
else {
plus = true;
for (int i = str.size() - 1; i >= 0; i -= 2) {
if (i - 1 >= 0)
listNumber[k] = symbol_in_numeral(str[i]) + symbol_in_numeral(str[i - 1]) * 10;
else listNumber[k] = symbol_in_numeral(str[i]);
k++;
}
}
}
updatingLength();
}
HugeInt HugeInt::operator-(HugeInt _HugeInt) {
HugeInt result = HugeInt();
if (_HugeInt.plus == this->plus) {
int length_tmp = _HugeInt.length > this->length ? _HugeInt.length : this->length;
char part_sub = 0;
int sub;
char tmp1, tmp2;
for (int i = 0; i < length_tmp; i++) {
tmp1 = listNumber[i];
tmp2 = _HugeInt.listNumber[i];
sub = ((int)listNumber[i] - (int)_HugeInt.listNumber[i] - (int)part_sub);
part_sub = 0;
if (sub < 0) {
sub += 100;
part_sub = 1;
}
//else if (sub == 0) //
//part_sub = 1; //
result.set_listNumber(i, sub);
}
if (part_sub != 0) {
part_sub = 0;
result.plus = !this->plus;
for (int i = 0; i < length_tmp; i++) {
sub = ((int)result.listNumber[i] + (int)part_sub - 100);//
part_sub = 0;
if (sub < 0) {
sub = abs(sub);
part_sub = 1;
}
//else if (sub == 0) //
//part_sub = 1; //
result.set_listNumber(i, sub % 100);
}
}
result.updatingLength();
return result;
}
else {
HugeInt lg1 = HugeInt(_HugeInt);
HugeInt lg2 = HugeInt(*this);
lg1.plus = !lg1.plus;
//HugeInt.plus = !HugeInt.plus;
return lg2 + lg1;
}
}
HugeInt HugeInt::operator+(HugeInt _HugeInt) {
HugeInt result = HugeInt();
if (_HugeInt.plus == this->plus) {
int length_tmp = _HugeInt.length > this->length ? _HugeInt.length : this->length;
char part_sum = 0;
char tmp1, tmp2;
for (int i = 0; i < length_tmp; i++) {
tmp1 = _HugeInt.listNumber[i];
tmp2 = listNumber[i];
result.set_listNumber(i, (_HugeInt.listNumber[i] + listNumber[i] + part_sum) % 100);
part_sum = (_HugeInt.listNumber[i] + listNumber[i] + part_sum) / 100;
}
if (part_sum != 0) {
result.set_listNumber(length_tmp, part_sum);
}
result.plus = plus;
result.updatingLength();
return result;
}
else {
if (_HugeInt.plus) {
//plus = !plus;
HugeInt lg1 = HugeInt(_HugeInt);
HugeInt lg2 = HugeInt(*this);
lg2.plus = !lg2.plus;
return lg1 - lg2;
}
else {
HugeInt lg1 = HugeInt(_HugeInt);
HugeInt lg2 = HugeInt(*this);
lg1.plus = !lg1.plus;
//HugeInt.plus != HugeInt.plus;
return lg2 - lg1;
}
}
}
HugeInt HugeInt::operator*(HugeInt _HugeInt) {
HugeInt result = HugeInt();
int part_mul;
int iter = 0;
HugeInt tmpHugeInt;
int tmp1, tmp2;
for (int i = 0; i < _HugeInt.length; i++) {
part_mul = 0;
tmpHugeInt = HugeInt();
for (int j = 0; j < length; j++) {
tmp1 = _HugeInt.listNumber[i];
tmp2 = listNumber[j];
iter = (int)_HugeInt.listNumber[i] * (int)listNumber[j] + (int)part_mul;
part_mul = iter / 100;
tmpHugeInt.set_listNumber(j + i, iter % 100);
}
if (part_mul != 0) {
tmpHugeInt.set_listNumber(tmpHugeInt.length, part_mul);
}
result = result + tmpHugeInt;
}
if (_HugeInt.plus != plus)
result.plus = false;
result.updatingLength();
return result;
}
HugeInt::HugeInt(string str) {
plus = true;
maxLength = 10;
listNumber = new char[maxLength];
length = 0;
setNumber(str);
}
HugeInt::HugeInt() {
plus = true;
maxLength = 10;
listNumber = new char[maxLength];
length = 0;
for (int i = length; i < maxLength; i++)
listNumber[i] = 0;
}
HugeInt::HugeInt(const HugeInt &lg) {
plus = lg.plus;
maxLength = lg.maxLength;
listNumber = new char[maxLength];
length = lg.length;
for (int i = 0; i < maxLength; i++)
if (i < lg.length){
listNumber[i] = lg.listNumber[i];
}
else{
listNumber[i] = 0;
}
}
HugeInt::~HugeInt() {
//delete[] listNumber;
}
main.cpp:
#include "stdafx.h"
#include "HugeInt.h"
int _tmain(int argc, _TCHAR* argv[])
{
/*
string num1, num2;
cout << "Enter the first number:" << endl;
cin >> num1;
cout << "Enter the second number:" << endl;
cin >> num2;
HugeInt hugeNum1 = HugeInt(num1);
HugeInt hugeNum2 = HugeInt(num2);
cout << "Entered the following numbers:" << endl;
cout << "First number: " << num1 << endl;
cout << "Second number: " << num2 << endl;
HugeInt sum = hugeNum1 + hugeNum2;
HugeInt sub = hugeNum1 - hugeNum2;
HugeInt mul = hugeNum1 * hugeNum2;
cout << "Summary = " << sum.toString() << endl;
cout << "Substruction = " << sub.toString() << endl;
cout << "Multiplacation = " << mul.toString() << endl;
*/
HugeInt longNumber1;
HugeInt longNumber2;
HugeInt longNumberRes;
/*
int firstTrue = 1837;
int secondTrue = -8108;
char buf[32];
itoa(firstTrue, buf, 10);
string firststr(buf);
itoa(secondTrue, buf, 10);
string secstr(buf);
longNumber1.setNumber(firststr);
longNumber2.setNumber(secstr);
longNumberRes = longNumber1 + longNumber2;
int res = atoi(longNumberRes.toString().c_str());
cout << "Good " << firstTrue << "+" << secondTrue << "=" << res << endl;
int firstFalse = 312;
int secondFalse = 712;
char buf2[32];
itoa(firstFalse, buf2, 10);
string firststr2(buf2);
itoa(secondFalse, buf2, 10);
string secstr2(buf2);
longNumber1.setNumber(firststr2);
longNumber2.setNumber(secstr2);
longNumberRes = longNumber1 - longNumber2;
int res2 = atoi(longNumberRes.toString().c_str());
cout << "Bad " << firstFalse << "-" << secondFalse << "=" << res2 << endl;
*/
for (int i = 0; i < 1000; i++)
{
int first = rand() % 20000 - 10000;
int second = rand() % 20000 - 10000;
char buf[32];
itoa(first, buf, 10);
string firststr(buf);
itoa(second, buf, 10);
string secstr(buf);
longNumber1.setNumber(firststr);
longNumber2.setNumber(secstr);
longNumberRes = longNumber1 - longNumber2;
int res = atoi(longNumberRes.toString().c_str());
if (res != first - second)
cout << i << " = "<< first << "+" << second << "=" << res << endl;
}
system("pause");
return 0;
}
It prints the following results when i am doing the test with 1000 random numbers (5 of 1000 results are incorrect):
48 = 6118+-7918=-1700
268 = -8887+4887=-3900
326 = 3169+-6169=-2900
474 = 212+-712=-400
492 = 1333+-7133=-5700
545 = 8352+-9552=-1100
617 = -4395+195=-4100
Looks like something wrong with minus operation, but i can not uderstand what exactly. Please, help, what is wrong in the implementation and how to fix it?

C++: Change of base function (i.e. hex to octal, decimal, etc.) - Output slightly off for hex values

I need to create a generic function that changes from any starting base, to any final base. I have everything down, except my original function took (and takes) an int value for the number that it converts to another base. I decided to just overload the function. I am Ok with changing between every base, but am slightly off when using my new function to take in a string hex value.
The code below should output 1235 for both functions. It does for the first one, but for the second, I am currently getting 1347. Decimal to Hex works fine - It's just the overloaded function (Hex to anything else) that is slightly off.
Thanks.
#include <iostream>
#include <stack>
#include <string>
#include <cmath>
using namespace std;
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, int num);
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, string s);
int main()
{
stack<int> myStack;
string hexNum = "4D3";
switchBasesFunction(myStack, 8, 10, 2323);
cout << endl << endl;
switchBasesFunction(myStack, 16, 10, hexNum);
return 0;
}
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, int num)
{
int totalVal = 0;
string s = to_string(num);
for (int i = 0; i < s.length(); i++)
{
myStack.push(s.at(i) - '0');
}
int k = 0;
while (myStack.size() > 0)
{
totalVal += (myStack.top() * pow(startBase, k++));
myStack.pop();
}
string s1;
while (totalVal > 0)
{
int temp = totalVal % finalBase;
totalVal = totalVal / finalBase;
char c;
if (temp < 10)
{
c = temp + '0';
s1 += c;
}
else
{
c = temp - 10 + 'A';
s1 += c;
}
}
for (int i = s1.length() - 1; i >= 0; i--)
{
cout << s1[i];
}
cout << endl << endl;
}
void switchBasesFunction(stack<int> & myStack, int startBase, int finalBase, string s)
{
int totalVal = 0;
for (int i = 0; i < s.length(); i++)
{
myStack.push(s.at(i) - '0');
}
int k = 0;
while (myStack.size() > 0)
{
totalVal += (myStack.top() * pow(startBase, k++));
myStack.pop();
}
string s1;
while (totalVal > 0)
{
int temp = totalVal % finalBase;
totalVal = totalVal / finalBase;
char c;
if (temp < 10)
{
c = temp + '0';
s1 += c;
}
else
{
c = temp - 10 + 'A';
s1 += c;
}
}
for (int i = s1.length() - 1; i >= 0; i--)
{
cout << s1[i];
}
cout << endl << endl;
}
Sorry, but I'm having issues understanding your code, so I thought I'd simplify it.
Here's the algorithm / code (untested):
void convert_to_base(const std::string& original_value,
unsigned int original_base,
std::string& final_value_str,
unsigned int final_base)
{
static const std::string digit_str =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if ((original_base > digit_str.length()) || (final_base > digit_str.length())
{
std::cerr << "Base value exceeds limit of " << digit_str.length() << ".\n";
return;
}
// Parse string from right to left, smallest value to largest.
// Convert to decimal.
unsigned int original_number = 0;
unsigned int digit_value = 0;
int index = 0;
for (index = original_value.length(); index > 0; --index)
{
std::string::size_type posn = digit_str.find(original_value[index];
if (posn == std::string::npos)
{
cerr << "unsupported digit encountered: " << original_value[index] << ".\n";
return;
}
digit_value = posn;
original_number = original_number * original_base + digit_value;
}
// Convert to a string of digits in the final base.
while (original_number != 0)
{
digit_value = original_number % final_base;
final_value_str.insert(0, 1, digit_str[digit_value]);
original_number = original_number / final_base;
}
}
*Warning: code not tested via compiler.**