//infint.cpp
#include<stdio.h>
#include<string>
#include<iostream>
#include<assert.h>
#include<sstream>
#include <algorithm>
#include"infint.hpp"
int charToInt(char c) {
return c - '0';
}
char intToChar(int n) {
return '0' + n;
}
Infint::Infint()
{
(*this).strData = "0";
(*this)._value=0;
}
Infint::Infint(int value)
:_value(value)
{
INT64ToString(); //将_value中的值保存在_strData中
}
Infint::Infint(const char* pData)
{
//"12345678" "234567qwe" "+" " " "0000123456"
if (NULL == pData)
{
assert(false);
return;
}
//处理符号位
char* pStr = (char*)pData;
char cSymbol = pData[0];
if ('+' == cSymbol || '-' == cSymbol)
pStr++;
else if (cSymbol >= '0' && cSymbol <= '9')
cSymbol = '+';
else
return;
//"0000123456"
int iDataLen = strlen(pData);
if (iDataLen > 1)
{
while ('0' == *pStr)
pStr++;
}
strData.resize(strlen(pData) + 1); //为_strData分配空间
strData[0] = cSymbol; //第0位保存符号
//"123456qwe"
_value = 0;
int iCount = 1;
while (*pStr >= '0' && *pStr <= '9')
{
_value = _value * 10 + (*pStr - '0');
strData[iCount++] = *pStr;
pStr++;
}
strData.resize(iCount);
if (cSymbol == '-')
_value = 0 - _value;
}
Infint Infint::operator+(const Infint & infint)
{
if (!IsINT64Overflow() && !infint.IsINT64Overflow())
{
if (strData[0] != infint.strData[0]) //异号
{
return Infint(_value + infint._value);
}
else //两个数同号
{
if ((_value >= 0 && infint._value <= MAX_INT64 - _value) ||
(_value < 0 && infint._value >= MIN_INT64 - _value))
return Infint(_value + infint._value);
}
}
if (strData[0] == infint.strData[0])
return Infint(add(strData, infint.strData).c_str());
else
return Infint(minus(strData, infint.strData).c_str());
}
Infint Infint::operator-(const Infint & infint)
{
if (!IsINT64Overflow() && !infint.IsINT64Overflow()) //两个数都没有溢出
{
if (strData[0] == infint.strData[0])//同号
{
return Infint(_value - infint._value);
}
else //异号
{
if ((_value >= 0 && MAX_INT64 + infint._value >= _value) ||
(_value < 0 && MIN_INT64 + infint._value <= _value)) //结果没有溢出
return Infint(_value - infint._value);
}
}
//至少有一个数溢出或结果溢出
if (strData[0] != infint.strData[0]) //异号相减,调用加法
return Infint(add(strData, infint.strData).c_str());
else //同号相减,调用减法
return Infint(minus(strData, infint.strData).c_str());
}
Infint Infint::operator*(const Infint & infint)
{
if (!IsINT64Overflow() && !infint.IsINT64Overflow()) //都没有溢出
{
if (_value == 0 || infint._value == 0)
{
return Infint((int)0);
}
if (strData[0] == infint.strData[0]) //同号,积为正
{
if ((_value > 0 && MAX_INT64 / _value >= infint._value) ||
(_value < 0 && MAX_INT64 / _value <= infint._value)) //积没有溢出
{
return Infint(_value * infint._value);
}
}
else //异号,积为负
{
if ((_value > 0 && MIN_INT64 / _value <= infint._value) ||
(_value < 0 && MIN_INT64 / _value >= infint._value)) //积没有溢出
{
return Infint(_value * infint._value);
}
}
}
return Infint(multiply(strData, infint.strData).c_str());
}
Infint Infint::operator++(int)
{
Infint infint=Infint(1);
if (!IsINT64Overflow() && !infint.IsINT64Overflow())
{
if (strData[0] != infint.strData[0]) //异号
{
return Infint(_value + infint._value);
}
else //两个数同号
{
if ((_value >= 0 && infint._value <= MAX_INT64 - _value) ||
(_value < 0 && infint._value >= MIN_INT64 - _value))
return Infint(_value + infint._value);
}
}
if (strData[0] == '+') {
std::string s = add(strData, infint.strData);
if (s[1] == '0') {
s = s.substr(2, s.length());
}
(*this).strData = s.c_str();
return (*this);
}
else {
(*this).strData = minus(infint.strData, strData).c_str();
return (*this);
}
}
Infint Infint::operator--(int)
{
Infint infint(-1);
if (!IsINT64Overflow() && !infint.IsINT64Overflow())
{
if (strData[0] != infint.strData[0]) //异号
{
(*this)._value = _value + infint._value;
return (*this);
}
else //两个数同号
{
if ((_value >= 0 && infint._value <= MAX_INT64 - _value) || (_value < 0 && infint._value >= MIN_INT64 - _value)) {
(*this)._value = _value + infint._value;
return (*this);
}
}
}
if (strData[0] == infint.strData[0]) {
std::string s = add(strData, infint.strData);
if (s[1] == '0') {
s = s.substr(0, 1) + s.substr( 2, s.length());
}
(*this).strData = s.c_str();
return (*this);
}
else {
(*this).strData = minus(strData, infint.strData).c_str();
return (*this);
}
}
Infint Infint::operator+=(const Infint & inf)
{
/*if (!IsINT64Overflow() && !inf.IsINT64Overflow())
{
if (strData[0] != inf.strData[0]) //异号
{
(*this)._value = _value + inf._value;
return (*this);
}
else //两个数同号
{
if ((_value >= 0 && inf._value <= MAX_INT64 - _value) || (_value < 0 && inf._value >= MIN_INT64 - _value)) {
(*this)._value = _value + inf._value;
return (*this);
}
}
}
if (strData[0] == inf.strData[0]) {
std::string s = add(strData, inf.strData);
if (s[1] == '0') {
s = s.substr(2, s.length());
}
(*this).strData = s.c_str();
return (*this);
}
else {
(*this).strData = minus(strData, inf.strData).c_str();
return (*this);
}*/
*this = *this + inf;
return *this;
}
Infint Infint::operator-=(const Infint & infint)
{
/*if (!IsINT64Overflow() && !infint.IsINT64Overflow()) //两个数都没有溢出
{
if (strData[0] == infint.strData[0])//同号
{
(*this)._value = _value - infint._value;
return (*this);
}
else //异号
{(*this)._value = _value - infint._value;
return (*this);
if ((_value >= 0 && MAX_INT64 + infint._value >= _value) ||
(_value < 0 && MIN_INT64 + infint._value <= _value)) {
(*this)._value = _value - infint._value;
return (*this);
}
}
}
if (strData[0] != infint.strData[0]) {
std::string s = add(strData, infint.strData);
if (s[1] == '0') {
s = s.substr(2, s.length());
}
(*this).strData = s.c_str();
return (*this);
}
else {
(*this).strData = minus(strData, infint.strData).c_str();
return (*this);
}*/
*this = *this - infint;
return *this;
}
Infint Infint::operator*=(const Infint & infint)
{
/*if (!IsINT64Overflow() && !infint.IsINT64Overflow()) //都没有溢出
{
if (_value == 0 || infint._value == 0)
{
(*this)._value = 0;
return (*this);
}
if (strData[0] == infint.strData[0]) //同号,积为正
{
if ((_value > 0 && MAX_INT64 / _value >= infint._value) ||
(_value < 0 && MAX_INT64 / _value <= infint._value)) //积没有溢出
{
(*this)._value = _value * infint._value;
return (*this);
}
}
else //异号,积为负
{
if ((_value > 0 && MIN_INT64 / _value <= infint._value) ||
(_value < 0 && MIN_INT64 / _value >= infint._value)) //积没有溢出
{
(*this)._value = _value * infint._value;
return (*this);
}
}
}
std::string s =multiply(strData, infint.strData);
if (infint.strData == "0") {
s = "0";
(*this).strData = s.c_str();
return (*this);
}
if (s[0] == '-') {
if (s[1] == '0') {
s = s.substr(0, 1) + s.substr(2, s.length());
}
}
else {
if (s[1] == '0')
s = s.substr(2, s.length());
}
(*this).strData = s.c_str();
return (*this);*/
*this = *this * infint;
return *this;
}
bool Infint::IsINT64Overflow() const
{
std::string temp("+9223372036854775807");
if (strData[0] == '-')
temp = "-9223372036854775808";
if (strData.size() < temp.size())
return false;
else if (strData.size() == temp.size() && strData <= temp)
return false;
return true;
}
void Infint::INT64ToString()
{
//处理符号位
char cSymbol = '+';
if (_value < 0)
cSymbol = '-';
int temp = _value;
while (temp)
{
if (cSymbol == '+')
strData.append(1, temp % 10 + '0');
else
strData.append(1, -(temp % 10) + '0');
temp /= 10;
}
if (temp == 0)
{
strData.append(1, temp + '0');
}
strData.append(1, cSymbol);
std::reverse(strData.begin(), strData.end());
}
bool Infint::IsLeftStrBig(const char * pLeft, int LSize, const char * pRight, int RSize)
{
assert(pLeft != NULL && pRight != NULL);
if ((LSize > RSize) ||
(LSize == RSize && strcmp(pLeft, pRight) >= 0))
return true;
else
return false;
}
char Infint::SubLoop(char * pLeft, int LSize, char * pRight, int RSize)
{
assert(pLeft != NULL && pRight != NULL);
char cRet = '0';
while (true)
{
if (!IsLeftStrBig(pLeft, LSize, pRight, RSize))
break;
int iLIdx = LSize - 1;
int iRIdx = RSize - 1;
while (iLIdx >= 0 && iRIdx >= 0)
{
char ret = pLeft[iLIdx] - '0';
ret -= pRight[iRIdx] - '0';
if (ret < 0)
{
pLeft[iLIdx - 1] -= 1;
ret += 10;
}
pLeft[iLIdx] = ret + '0';
iLIdx--;
iRIdx--;
}
while (*pLeft == '0' && LSize > 0)
{
pLeft++;
LSize--;
}
cRet++;
}
return cRet;
}
std::string Infint::add(std::string left, std::string right)
{
//让left保存位数大的数
int iLeftSize = left.size();
int iRightSize = right.size();
if (iLeftSize < iRightSize)
{
std::swap(left, right);
std::swap(iLeftSize, iRightSize);
}
//相加
std::string strRet;
strRet.resize(iLeftSize + 1);
strRet[0] = left[0]; //符号位
char Step = 0; //进位
for (int iIdx = 1; iIdx < iLeftSize; ++iIdx)
{
char cRet = left[iLeftSize - iIdx] - '0' + Step;
if (iIdx < iRightSize)
cRet += right[iRightSize - iIdx] - '0';
strRet[iLeftSize - iIdx + 1] = cRet % 10 + '0';
Step = cRet / 10;
}
strRet[1] = Step + '0';
return strRet;
}
std::string Infint::minus(std::string left, std::string right)
{
int iLeftSize = left.size();
int iRightSize = right.size();
char cSymbol = left[0]; //差的符号位
if ((iLeftSize < iRightSize) ||
(iLeftSize == iRightSize && left < right))
{
std::swap(left, right);
std::swap(iLeftSize, iRightSize);
if (cSymbol == '+')
cSymbol = '-';
else
cSymbol = '+';
}
//相减
std::string strRet; //保存差
strRet.resize(left.size()); //先设置和左操作数一样大的空间
strRet[0] = cSymbol; //符号位
for (int Idx = 1; Idx < iLeftSize; ++Idx)
{
char cRet = left[iLeftSize - Idx] - '0';
if (Idx < iRightSize)
cRet -= (right[iRightSize - Idx] - '0');
if (cRet < 0) //有借位
{
left[iLeftSize - Idx - 1] -= 1;
cRet += 10;
}
strRet[iLeftSize - Idx] = cRet + '0';
}
return strRet;
}
std::string Infint::multiply(std::string left, std::string right)
{
//确定符号位
char cSymbol = '+';
if (left[0] != right[0])
cSymbol = '-';
//使左操作数位数小于右操作数位数
int iLeftSize = left.size();
int iRightSize = right.size();
if (iLeftSize > iRightSize)
{
std::swap(left, right);
std::swap(iLeftSize, iRightSize);
}
std::string strRet;
//strRet.resize(iLeftSize+iRightSize-1);
strRet.assign(iLeftSize + iRightSize - 1, '0');
strRet[0] = cSymbol;
int iRetLen = strRet.size();
int iOffset = 0; //偏移
for (int iLeftIndex = 1; iLeftIndex < iLeftSize; ++iLeftIndex)
{
char cLeft = left[iLeftSize - iLeftIndex] - '0';
if (cLeft == 0) //当左操作数中有0时,直接左移,不计算
{
++iOffset;
continue;
}
char cStep = 0;
for (int iRightIndex = 1; iRightIndex < iRightSize; ++iRightIndex)
{
char cRet = cLeft*(right[iRightSize - iRightIndex] - '0') + cStep;
cRet += strRet[iRetLen - iRightIndex - iOffset] - '0';
strRet[iRetLen - iRightIndex - iOffset] = (cRet % 10) + '0';
cStep = cRet / 10;
}
strRet[iRetLen - iRightSize - iOffset] += cStep;
++iOffset;
}
return strRet;
}
/*
+
-
++
--
+=
-=
*
*=
=
*/
std::ostream & operator<<(std::ostream & _cout, const Infint & bigdata)
{
if (!bigdata.IsINT64Overflow()) //_value没有溢出
{
_cout << bigdata._value;
}
else //_value溢出
{
char* pData = (char*)bigdata.strData.c_str();
if ('+' == pData[0])
pData++;
_cout << pData;
}
return _cout;
}
'C++ > 학교 숙제' 카테고리의 다른 글
session_4_ex infint.hpp (완성) (0) | 2018.04.22 |
---|---|
session_6_ex 답 (0) | 2018.04.22 |
session_6_ex (0) | 2018.04.22 |
string 문자열 뺄셈계산 (0) | 2018.04.15 |
string 문자열 덧셈계산 (0) | 2018.04.14 |
댓글