c++训练

C++练习:设计一个超长整数类


仅供参考

题目

定义并实现超长整数类doublelong,要求如下:
64位数据长度,有符号
支持+、-、*、/运算
支持+=、-=、/=运算
支持cin>>和cout<<操作

设计思想

根据题意,创造一个超长整数类doublelong类。因为整数长度可能非常长,故使用指针创造动态数组的方式来存储数据,并用int型的length来表示其实际长度,用bool型的symbol来表示其符号。
对于构造函数重载,需要重载可以输入字符来转化的构造函数、可以将原本的long long型数据转化成doublelong类的构造函数,以及对于数组进行装载的构造函数。 而对于复制构造函数,因为该类中具有指针,故必须重载复制构造函数以达到深复制的目的。
接着重载+,-,*,/,+=,-=,*=,/=运算符。
对于+运算符,考虑到符号的不同,分为两种情况:同符号相加以及异号相加。对于同号相加,设置进位,直接将长度短的数字加到长度长的数字上。而对于异号相加,相当于减法,则设置借位,用长度长的数字减去长度短的数字。若碰到异号同长度的情况,则从最高位开始逐级判断其大小,最后用大的数字减去小的数字。
对于-运算符,将减数取反,即变成了加法,进行加运算即可。
对于*运算符,模拟手算乘法的过程,即将一个数与另一个数的每一位相乘,最后结果带位数相加。这里进行了简便算法,即先将每一位相乘,得到的结果再进行变换,最后形成数组中的每一位只有一个数字的状态。
对于/运算符,这里考虑减法计算,即先将除数扩大到与被除数相同位数,将两者相减,直到结果即将为负数时停止,然后除数退位,再减……以此类推,直到除数回到原来的位置为止。结果即为除数进位数与相减的次数之积的总和。
而对于+=,-=,*=,/=运算符,则将其拆开成例如a=a+b的形式直接计算。
再重载>>与<<运算符。因为两个运算符是在istream和ostream类中的,故无法直接重载。在此将两个重载设为友元函数后进行重载。
在该类中,还要考虑强制类型转换问题,因为在long long型的数字与doublelong型数字进行运算时,long long型应当先转化为doublelong型,再进行运算,而运算结果也应为doublelong型。
最后在主函数中对于10个运算符进行测试。

代码

doublelong.h

#pragma once
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
#ifndef _DOUBLELONG_H_
#define _DOUBLELONG_H_
class doublelong {
private:
	int* num;
	bool symbol;
	int length;
public:

	doublelong() {
		symbol = true;
		num = NULL;
		length = 0;
	}

	doublelong(string t) {
		num = new int[t.length()];
		if (t[0] != '-') {
			length = t.length();
			symbol = true;
			for (int i = t.length() - 1; i >= 0; i--) {
				num[t.length() - i - 1] = t[i] - '0';
			}
		}
		else {
			length = t.length() - 1;
			symbol = false;
			for (int i = t.length() - 1; i > 0; i--) {
				num[t.length() - i - 1] = t[i] - '0';
			}
		}
	}

	doublelong(long long t) {

		if (t >= 0) symbol = true;
		else {
			symbol = false;
			t = -t;
		}
		num = new int[100];
		if (t == 0) {
			num[0] = 0;
			length = 1;
			return;
		}
		int cnt = 0;
		while (t != 0) {
			num[cnt++] = t % 10;
			t /= 10;
		}
		
		length = cnt;

	}

	doublelong(int t[], int len, bool sym) {
		num = new int[len];
		length = len;
		for (int i = 0; i < len; i++)  num[i] = t[i];
		symbol = sym;
	}



	doublelong(const doublelong & t) {
		num = new int[t.length];
		length = t.length;
		for (int i = 0; i < length; i++) num[i] = t.num[i];
		symbol = t.symbol;
	}

	void operator = (long long x);


	doublelong operator + (doublelong & x);
	doublelong operator - (doublelong & x);
	doublelong operator * (doublelong & x);
	doublelong operator / (doublelong & x);
	doublelong& operator += (doublelong & x);
	doublelong& operator -= (doublelong & x);
	doublelong& operator *= (doublelong & x);
	doublelong& operator /= (doublelong & x);



	doublelong operator + (long long x);
	doublelong operator - (long long x);
	doublelong operator * (long long x);
	doublelong operator / (long long x);
	doublelong& operator += (long long x);
	doublelong& operator -= (long long x);
	doublelong& operator *= (long long x);
	doublelong& operator /= (long long x);

	friend istream& operator >> (istream & in, doublelong & x);
	friend ostream& operator << (ostream & out, doublelong & x);
};

void doublelong::operator = (long long t) {

	if (t >= 0) symbol = true;
	else {
		symbol = false;
		t = -t;
	}
	num = new int[100];
	if (t == 0) {
		num[0] = 0;
		length = 1;
		return;
	}
	int cnt = 0;
	while (t != 0) {
		num[cnt++] = t % 10;
		t /= 10;
	}
	
	length = cnt;

}



doublelong doublelong::operator + (doublelong & x) {
	int len = (length > x.length ? length : x.length) + 1;

	bool symj = symbol == x.symbol ? true : false;
	bool sym;
	int* t = new int[len];
	for (int i = 0; i < len; i++) t[i] = 0;
	int up = 0;
	if (symj) {
		sym = symbol;
		if (length > x.length) {
			for (int i = 0; i < length; i++) t[i] = num[i];
			for (int i = 0; i < x.length; i++) {
				t[i] += x.num[i] + up;
				up = t[i] / 10;
				t[i] = t[i] % 10;
			}
			t[x.length] += up;
			for (int i = x.length; i < length; i++)
				if (t[i] >= 10) {
					t[i + 1]++;
					t[i] = t[i] - 10;
				}
			if (t[length] == 0) len -= 1;
		}
		else {
			for (int i = 0; i < x.length; i++) t[i] = x.num[i];
			for (int i = 0; i < length; i++) {
				t[i] += num[i] + up;
				up = t[i] / 10;
				t[i] = t[i] % 10;
			}
			t[x.length] += up;
			for (int i = length; i < x.length; i++)
				if (t[i] >= 10) {
					t[i + 1]++;
					t[i] = t[i] - 10;
				}
			if (t[x.length] == 0) len -= 1;
		}
	}
	else {
		if (length > x.length) {
			sym = symbol;
			for (int i = 0; i < length; i++) t[i] = num[i];
			for (int i = 0; i < x.length; i++) {
				t[i] -= (up + x.num[i]);
				if (t[i] < 0) {
					t[i] = 10 + t[i];
					up = 1;
				}
				else up = 0;
			}
			t[x.length] -= up;
			for (int i = x.length; i < length; i++) {
				if (t[i] < 0) {
					t[i + 1]--;
					t[i] = 10 + t[i];
				}
			}

			if (t[len - 2] == 0) {
				len -= 2;
			}
			else len -= 1;

		}
		else if (length < x.length) {
			sym = x.symbol;
			for (int i = 0; i < x.length; i++) t[i] = x.num[i];
			for (int i = 0; i < length; i++) {
				t[i] -= (up + num[i]);
				if (t[i] < 0) {
					t[i] = 10 + t[i];
					up = 1;
				}
				else up = 0;
			}
			t[length] -= up;
			for (int i = length; i < x.length; i++) {
				if (t[i] < 0) {
					t[i + 1]--;
					t[i] = 10 + t[i];
				}
			}
			if (t[len - 2] == 0) {
				len -= 2;
			}
			else len -= 1;
		}
		else {
			int m = len - 2;
			while (num[m] == x.num[m]) m--;
			if (m < 0) {
				len = 1;
				t[0] = 0;
				sym = true;
			}
			else {
				len = m + 1;
				if (num[len - 1] > x.num[len - 1]) {
					sym = symbol;
					for (int i = 0; i < len; i++) t[i] = num[i];
					for (int i = 0; i < len; i++) {
						t[i] -= (up + x.num[i]);
						if (t[i] < 0) {
							t[i] = 10 + t[i];
							up = 1;
						}
						else up = 0;
					}
					
					t[len - 1] -= up;
					if (t[len - 1] == 0) {
						len -= 1;
					}

					
				}
				else {
					sym = x.symbol;
					for (int i = 0; i < x.length; i++) t[i] = x.num[i];
					for (int i = 0; i < length; i++) {
						t[i] -= (up + num[i]);
						if (t[i] < 0) {
							t[i] = 10 + t[i];
							up = 1;
						}
						else up = 0;
					}
					t[len - 1] -= up;
					if (t[len - 1] == 0) {
						len -= 1;
					}
					
				}
			}
		}
	}
	return doublelong(t, len, sym);
}
doublelong doublelong::operator+(long long x) {
	doublelong t(x);
	return *this + t;
}
doublelong& doublelong::operator += (doublelong & x) {
	*this = *this + x;
	return *this;
}
doublelong& doublelong::operator += (long long x) {
	*this = *this + x;
	return *this;
}







doublelong doublelong::operator-(doublelong & x) {
	x.symbol = !x.symbol;
	doublelong y;
	y = *this + x;
	x.symbol = !x.symbol;
	return y;
}
doublelong doublelong::operator-(long long x) {
	doublelong t(x);
	return *this - t;
}
doublelong& doublelong::operator -= (doublelong & x) {
	*this = *this - x;
	return *this;
}
doublelong& doublelong::operator -= (long long x) {
	*this = *this - x;
	return *this;
}







doublelong doublelong::operator*(doublelong & x) {
	int* t = new int[length + x.length];
	for (int i = 0; i < length + x.length; i++) {
		t[i] = 0;
	}
	int len = 0;
	for (int i = 0; i < length; i++)
		for (int j = 0; j < x.length; j++) {
			t[i + j] += num[i] * x.num[j];
		}

	for (int i = 0; i < length + x.length - 1; i++) {
		t[i + 1] += t[i] / 10;
		t[i] = t[i] % 10;
	}


	for (int i = length + x.length - 1; i >= 0; i--)
		if (t[i] != 0) {
			len = i + 1;
			break;
		}
	bool sym = !(symbol ^ x.symbol);
	if (len == 0) len = 1;
	return doublelong(t, len, sym);
}
doublelong doublelong::operator*(long long x) {
	doublelong t(x);
	return *this* t;
}
doublelong& doublelong::operator *= (doublelong & x) {
	*this = *this * x;
	return *this;
}
doublelong& doublelong::operator *= (long long x) {
	*this = *this * x;
	return *this;
}







doublelong doublelong::operator/(doublelong & x) {

	if (x.length == 1 && x.num[0] == 0) {
		cout << "divide error!!!!!!!!!!!!!!" << endl;
		return 0;
	}

	doublelong ans = 0;

	if (length >= x.length) {
		doublelong t, th = *this;

		th.symbol = true;
		doublelong* pow = new doublelong[length - x.length + 1];
		pow[0] = 1;
		for (int i = 0; i < length - x.length; i++) pow[i + 1] = pow[i] * 10;//指数表
		for (int i = length - x.length; i >= 0; i--) {
			t = x * pow[i];

			t.symbol = true;
			while (1) {//这个最多进行9次
				doublelong y = th - t;
				if (!y.symbol) break;
				th = th - t;
				
				ans = ans + pow[i];
			
			}
		}
	}
	else ans = 0;
	ans.symbol = !(this->symbol ^ x.symbol);
	return ans;
}
doublelong doublelong::operator/(long long x) {
	doublelong y(x);
	return *this / y;
}
doublelong& doublelong::operator /= (doublelong & x) {
	*this = *this / x;
	return *this;
}
doublelong& doublelong::operator /= (long long x) {
	*this = *this / x;
	return *this;
}



istream& operator >>(istream & in, doublelong & x) {
	string s;
	in >> s;
	x = s;
	return in;
}

ostream& operator <<(ostream & out, doublelong & x) {
	if (!x.symbol&&!(x.num[0]==0&&x.length==1)) out << "-";
	for (int i = x.length - 1; i >= 0; i--) {
		out << x.num[i];
	}
	return out;
}

#endif // !_DOUBLELONG_H_

main函数

#include<cstdio>
#include"doublelong.h"
using namespace std;

int main() {
	doublelong x1, x2;
	doublelong y;
	cin >> x1 >> x2;
	y = x1 + x2;
	cout << "x1+x2:" << y << endl;
	y = x1 - x2;
	cout << "x1-x2:" << y << endl;
	y = x1 * x2;
	cout << "x1*x2:" << y << endl;  
	y = x1 / x2;
	cout << "x1/x2:" << y << endl;
	x1 += x2;
	cout << "x1+=x2:" << x1 << endl;
	x1 -= x2;
	cout << "x1-=x2:" << x1 << endl;
	x1 *= x2;
	cout << "x1*=x2:" << x1 << endl;
	x1 /= x2;
	cout << "x1/=x2:" << x1 << endl;
	
	return 0;

}
  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值