c++大整数类
@TOC
仅供参考
题目
定义并实现超长整数类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;
}