实现了 + - * ,除法还没有完成。
利用string类模拟手工加减乘。
头文件
#pragma once
#include <string>
#include <iostream>
using namespace std;
typedef long long INT64;
class BigData {
public:
friend ostream& operator << (ostream& cout, BigData);
BigData();
BigData(const string& _strData);
string Mul(string strLeft, string strRight);
string Sub(string strLeft, string strRight);
string Add(string strLeft, string strRight);
BigData operator*(const BigData& bg);
BigData operator-(const BigData& bg);
BigData operator+(const BigData& bg);
private:
string _strData;
};
#include "BigData.h"
#include <algorithm>
BigData::BigData()
: _strData("")
{
}
BigData::BigData(const std::string& str)
: _strData(str)
{
}
BigData BigData::operator-(const BigData& bg)
{
BigData tmp;
tmp._strData = Sub(this->_strData, bg._strData);
return tmp;
}
BigData BigData::operator+(const BigData& bg)
{
BigData tmp;
tmp._strData = Add(this->_strData, bg._strData);
return tmp;
}
string _Add(std::string strLeft, std::string strRight);
string BigData::Add(std::string strLeft, std::string strRight)
{
if (strLeft[0] == strRight[0]) {
return _Add(strLeft, strRight);
}
else {
//异号相加变为同号相减
if (strLeft[0] == '-') {
strLeft[0] = '+';
strLeft.swap(strRight);
}
else {
strRight[0] = '+';
}
return BigData::Sub(strLeft, strRight);
}
}
string _Add(std::string strLeft, std::string strRight)
{
int sizeLeft = strLeft.size();
int sizeRight = strRight.size();
if (sizeLeft < sizeRight) {
strLeft.swap(strRight);
swap(sizeLeft, sizeRight);
}
string strRet(sizeLeft +1 , '0');
strRet[0] = strLeft[0];
int idxL = sizeLeft - 1;
int idxR = sizeRight - 1;
for (; idxL >0; idxL--, idxR--) {
int c = strLeft[idxL] - '0';
if (idxR >= 1) {
c = c + strRight[idxR] - '0';
}
if (c > 9) {
strLeft[idxL - 1] += 1;
c -= 10;
}
strRet[idxL+1] = c + '0';
}
return strRet;
}
string _Sub(std::string strLeft, std::string strRight);
string BigData::Sub(std::string strLeft, std::string strRight)
{
if (strLeft[0] == strRight[0]) {
//如果为负-负,变为正-正的形式
if (strLeft[0] == '-') {
strRight[0] = '+';
strLeft[0] = '+';
strLeft.swap(strRight);
}
return _Sub(strLeft, strRight);
}
else {
//异号相减,变成同号相加
if (strRight[0] == '-') {
strRight[0] = '+';
}
else {
strRight[0] = '-';
}
return BigData::Add(strLeft, strRight);
}
}
//同号
string _Sub(std::string strLeft, std::string strRight) {
//有没有超出范围
int LSize = strLeft.size();
int RSize = strRight.size();
//调整被减数顺序
char symbol = '+';
if (LSize < RSize || LSize == RSize && strLeft < strRight) {
strLeft.swap(strRight);
swap(LSize, RSize);
symbol = '-';
}
std::string strRet(LSize, '0');
strRet[0] = symbol;
//取最低位相减
for (int idxL = LSize - 1, idxR = RSize - 1; idxL > 0; idxL--, idxR--) {
char c = strLeft[idxL] - '0';
if (idxR >= 1) {
c = c - (strRight[idxR] - '0');
}
if (c < 0) {
strLeft[idxL - 1] -= 1;//借位
c += 10;
}
strRet[idxL] = c + '0';
}
return strRet;
}
ostream& operator << (ostream& cout, BigData bg)
{
cout <<bg._strData;
return cout;
}
BigData BigData::operator*(const BigData& bg)
{
/*
检测合法性,比较麻烦
if (IsINT64Overflow() && bg.IsINT64Overflow()) {
if (0 == _value) {
return BigData("+0");
}
//同号相乘
if (_strData[0] == bg._strData[0]) {
//乘完的结果是否合法
if (('+' == _strData[0] && maxValue / _value >= bg._value)
||('-' == _strData[0] && maxValue / _value <= bg._value)) {
return BigData(_value / bg._value);
}
}
}
else {
//异号
if (0 == _value) {
return BigData("+0");
}
if (_strData[0] == bg._strData[0]) {
//乘完的结果是否合法
//-10 / 2 = -5 <= -3
if (('+' == _strData[0] && minValue / _value <= bg._value)
|| ('-' == _strData[0] && minValue / _value >= bg._value)) {
return BigData(_value / bg._value);
}
}
}
*/
return BigData(Mul(_strData, bg._strData));
}
string BigData::Mul(string strLeft, string strRight) {
//模拟过程,每次取右操作数一位和左数相乘,临时结果ret
char symbol = '+';
if (strLeft[0] != strRight[0]) {
symbol = '-';
}
int LSize = strLeft.size();
int RSize = strRight.size();
if (LSize > RSize) {
swap(strLeft, strRight);
swap(LSize, RSize);
}
//结果最多位数
std::string strRet(LSize + RSize - 1, '0');
strRet[0] = symbol;
int offset = 0;
for (int idxL = LSize - 1; idxL > 0; idxL--) {
//进位清零
char cStep = 0;
//取左操作数当前位
char cLeft = strLeft[idxL] - '0';
//用cLeft乘右操作数每一位
for (int idxR = RSize - 1; idxR > 0; idxR--) {
char cRet = cLeft * (strRight[idxR] - '0') + cStep;
//偏移后需要加上原来的位的数据
cRet += strRet[LSize + idxR - 1 - offset] - '0';
cStep = cRet / 10;
cRet = cRet % 10;
//保存结果的最低位
strRet[LSize + idxR -1 - offset] = cRet + '0';
}
strRet[LSize - 1 - offset] = cStep + '0';
offset++;
}
return strRet;
}
/*除法思路
确定每次除的位数,如果被除数大于除数,结果补零除数增加一位。具体除法用循环相减。
*/
测试用例
#include "BigData.h"
#include <iostream>
using namespace std;
int main() {
BigData bg1("+10005");
BigData bg2("-3216");
cout << bg1 + bg1 << endl << bg2 + bg2 << endl << bg1 - bg1 << endl << bg2 - bg2 << endl;
cout << bg1 + bg2 << endl << bg2 + bg1 << endl << bg1 - bg2 << endl << bg2 - bg1 << endl;
BigData bg3("+199");
BigData bg4("+9999");
cout << bg3*bg4;
}