본문 바로가기
C++/학교 숙제

session_4_ex infint.cpp(완성)

by Beijing_KingGod 2018. 4. 22.

//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

댓글