#include<iostream>
#include<string.h>
#include<assert.h>
using namespace std;

typedef long long INT64; 
const INT64 MAX_INT64 = 0x7fffffffffffffff;// 9223372036854775807;
const INT64 MIN_INT64 = 0x8000000000000000;//-9223372036854775808;
class BigData
{
public:
 BigData(INT64 value = 0);
 BigData(const string pData);
 
 BigData operator+(const BigData bigdata);
 BigData operator-(const BigData bigdata);
 BigData operator*(const BigData bigdata);
 BigData operator/(const BigData bigdata);
 
 ~BigData();
 
 void Print();
 
private:
 bool PDataIsOverINT64()const;
 friend std::ostream&operator<<(std::ostream& _cout, const BigData& bigdata);//不能在_cout前加const   ->_cout<<10<<endl;将不能通过
  
 BigData Add(string pData1, string pData2);//并不一定要写成成员函数 (也可以写成一般函数被使用)
 BigData Sub(string pData1, string pData2);
 BigData Mul(string pData1, string pData2);
 BigData Div(string pData1, string pData2);
 
private:
 INT64 _value;
 string _pData;
};
 

BigData::BigData(INT64 value)//若输入的数值位数大于MAX_DATA,系统编译不通过,当位数一致且大于时,转为负,无能为力
 :_value(value)
{
 //在_pData中加入value
 void Invert(string& pdata);
 size_t i = 0;
 INT64 tmp = 0;
 _pData.append(1, '+');
 if (value < 0)
 {
  _pData[0] = '-';
  value *= -1;
 }
 while (value != 0)
 {
  tmp = value % 10;
  _pData.append(1, (char)(tmp + '0'));
  value /= 10;
 }
 Invert(_pData);
}
 
BigData::BigData(const string  pData)
{
 //解决各种特殊情况
 //{"1234" "0001234"  "1564adf"  "   "  "+(-)12345" NULL }
 //参考atoi()函数处理办法
  
 
 //跳过符号将输入字符串都归为一般
 
//  //判是否是数字字符isdigit(int c)是-1/否0  还有判空字符(宏定义) isspace(int c)  头文件<ctype.h>
 
 char* tmp = (char*)&pData[0];
 _pData.append(1, '+');  //添加符号(默认为'+')
 
 if ((*tmp < '0' || *tmp > '9') && *tmp != ' '&& *tmp != '+'&& *tmp != '-'&& *tmp != '\t')  //排除其他符号
 {
  //cout << "false" << endl;
  _pData.append(1, '0');
  _value = 0;
  return;
 }
 
 while(isspace(*tmp)) //while (*tmp==' ')   //消除前面的空格(tab)
 {
  tmp++;
 }
 
 if (*tmp == '+' || *tmp == '-')  //跳过符号/修正符号
 {
  if (*tmp == '-')
  {
   _pData[0] = '-';
  }
  tmp++;
 }
 
 while (*tmp == '0')   //消除前面的0(必须先消除空格,再消除0,最后判断+(-))
 {
  tmp++;
 }
 
//*********************
 //一个一个追加效率不高-->转化为一次开辟
 //while(isdigit(*tmp))  //while (*tmp >= '0'&& *tmp <= '9')
 //{
 // _pData.append(1, *tmp++);
 //}
//*********************
 
 _pData.resize(strlen(tmp) + 1);
 int i = 1;
 while (isdigit(*tmp))
 {
  _pData[i++] = *tmp++;
 }
 
 if (*tmp != '\0')
 {
  //cout << "false" << endl;
  _value = 0;
  return;
 }
 
 //若超出INT64表示的范围则用string管理,否则用INT64,string综合管理
 if (!PDataIsOverINT64())
 {
  size_t i = 1;
  _value = 0;
  for (i = 1; i < _pData.size(); i++)
  {
   _value = _value * 10 + _pData[i] - '0';
  }
  if (_pData[0] == '-')
   _value *= -1;
 }
 
}
 
BigData::~BigData()
{}
 
bool BigData::PDataIsOverINT64()const
{
 std::string tmp("+9223372036854775807");
 if (_pData[0] == '-')
 {
  tmp = "-9223372036854775808";
 }
 
 if ((_pData.size() < tmp.size())||
  (_pData.size() == tmp.size() && _pData <= tmp))
 {
  return false;
 }
 return true;
 
}
 
std::ostream& operator<<(std::ostream& _cout, const BigData& bigdata)//不能在_cout前加const   ->_cout<<10<<endl;将不能通过
{
 if (!bigdata.PDataIsOverINT64())
 {
  _cout << bigdata._value;
 }
 else
 {
  char* tmp = (char*)&bigdata._pData[0];
  if ('+' == *tmp)
  {
   tmp++;
  }
  while (*tmp)
  {
   _cout << *tmp++;
  }
  //_cout << endl;
 }
 return _cout;
}
 
void BigData::Print()
{
 if (!PDataIsOverINT64())
 {
  cout << _value << endl;   //printf("%lld\n", _value);
  return;
 }
 if (*(char*)&_pData[0] == '+')
 {
 cout<<_pData[1]<<endl;
  return;
 }
 
  cout<<_pData[0]<<endl;
}
 
void Invert(string& pdata)
{
 int left = 1;
 int right = pdata.size() - 1;
 while (left < right)
 {
  swap(pdata[left++], pdata[right--]);
 }
}
 
BigData BigData:: operator+(const BigData bigdata)
{
 //1、都在INT64范围内<运算后在范围内,运算后不在范围内>(再进行构造可以解决)
 //2、都不在INT64范围内<运算后在范围内,运算后不在范围内>
 //3、一个在一个不在<运算后在范围内,运算后不在范围内>
 //
 //如果全部用string进行计算,就达不到数值小时用基本类型提高运算的目的
 //由于实现结构是若在INT64范围内_value与_pData共同管理,若不在只由_pData管理
 
 //所以,可以将上面分化成两类<1、都在范围内(<运算后在范围内,运算后不在范围内>) 2、至少有一个不在范围内>
 
 
 if (!PDataIsOverINT64() && !bigdata.PDataIsOverINT64())
 {
  if (_pData[0] != bigdata._pData[0])//若异号,则肯定不会溢出
  {
   return BigData(_value + bigdata._value);
  }
  else //同号
  {
   if (_pData[0] == '+')//为正
   {
    if (_value <= MAX_INT64 - bigdata._value)//结果不溢出
    {
     return BigData(_value + bigdata._value);
    }
    else //结果溢出
    {
     return BigData(Add(_pData, bigdata._pData));
    }
   }
   else //为负
   {
    if (_value >= MIN_INT64 - bigdata._value)//结果不溢出
    {
     return BigData(_value + bigdata._value);
    }
    else //结果溢出
    {
     return BigData(Add(_pData, bigdata._pData));
    }
   }
  }
 }
 else//至少有一个溢出
 {
  return BigData(Add(_pData, bigdata._pData));
 }
}
 
 
 
BigData BigData:: operator-(const BigData bigdata)
{
 //1、都在范围内(运算后在范围内,运算后不在范围内) 
 //2、至少有一个不在范围内
 
 if (!PDataIsOverINT64() && !bigdata.PDataIsOverINT64())
 {
  //同号相减不可能溢出,异号相减才可能溢出
 
  if (_pData[0] == bigdata._pData[0])//同号
  {
   return BigData(_value - bigdata._value);
  }
  else// 异号
  {
   if (_pData[0] == '+')//第一个为正,第二个为负
   {
    if (_value < MAX_INT64 + bigdata._value)//结果不溢出
    {
     return BigData(_value - bigdata._value);
    }
    else   //结果溢出
    {
     return Sub(_pData, bigdata._pData);
    }
   }
   else //第一个为负,第二个为正
   {
    if (_value > MIN_INT64 + bigdata._value)//结果不溢出
    {
     return BigData(_value - bigdata._value);
    }
    else   //结果溢出
    {
     return Sub(_pData, bigdata._pData);
    }
   }
  }
 }
 else
 {
  return Sub(_pData, bigdata._pData);
 }
}
 
void _EachAdd0(string& pdate) //各项添加'0'
{
 int size = pdate.size();
 int i = 1;
 for (i = 1; i < size; i++)
 {
  pdate[i] += '0';
 }
}
 
void _EachSub0(string& pdate) //各项去'0'
{
 int size = pdate.size();
 int i = 1;
 for (i = 1; i < size; i++)
 {
  pdate[i] -= '0';
 }
}
 
BigData BigData:: Add(string pData1, string pData2)
{
 //转化为string中从低到高字符相加
 //若同号 就相加,若异号,转为减
 
 if (pData1[0] != pData2[0])//异号
 {
  if (pData1[0] == '+')
  {
   pData2[0] = '+';
   return Sub(pData1, pData2);
  }
  else
  {
   pData1[0] = '+';
   return Sub(pData2, pData1);
  }
 }
 else//同号  
 {
  //判断哪个位数多,放在前面
  if (pData1.size() < pData2.size())
  {
   swap(pData1, pData2);
  }
 
  std::string tmp;
  int size1 = pData1.size();
  int size2 = pData2.size();
  int sizet = size1 + 1;
  int flag = 0;
  tmp.resize(size1 + 1);
  tmp[0] = pData1[0];
 
  for (int i = 0; i < size1 - 1; i++)
  {
   flag = 0;
   char cur = '0';
   if (size2 - 1 - i > 0)
   {
    cur = pData2[size2 - 1 - i];
   }
   tmp[sizet - i-1] = pData1[size1 - 1 - i] + cur - 2 * '0';//tmp存数值而不是数字字符
   if (tmp[size1 - i] / 10 == 1)
   {
    flag = 1;
    tmp[size1 - i] %= 10;
   }
    
   pData1[size1 - i - 2] += flag;
  }
  tmp[1] = flag;
  _EachAdd0(tmp);
 
  return BigData(tmp);
 }
}
 
 
BigData BigData::Sub(string pData1, string pData2)
{
 //转化为string中从低到高字符相减
 //若同号 就相减(注意前后位数不同),若异号,转为加
 
 if (pData1[0] != pData2[0])//异号
 {
  if (pData1[0] == '+')
  {
   pData2[0] = '+';
   return Add(pData1, pData2);
  }
  else
  {
   pData2[0] = '-';
   return Add(pData1, pData2);
  }
 }
 else  //同号
 {
  //取数值的符号,将较大值放在前面
 
  if (pData1.size() < pData2.size() ||
   (pData1.size() == pData2.size() && (strcmp(pData1.c_str(), pData2.c_str()) < 0)))
  {
   if (pData1[0] == '+')
   {
    pData2[0] = '-';
   }
   else
   {
    pData2[0] = '+';
   }
   swap(pData1, pData2);   
  }
  std::string tmp;
  int size1 = pData1.size();
  int size2 = pData2.size();
  int sizet = size1;
  int flag = 0;
  tmp.resize(sizet);
  tmp[0] = pData1[0];
  for (int i = 0; i < size1 - 1; i++)
  {
   flag = 0;
   int cur = 0;
   if (i < size2 - 1)
   {
    cur = pData1[size1 - i - 1] - pData2[size2 - i - 1];
   }
   else
   {
    cur = pData1[size1 - i - 1] - '0';
   }
   if (cur < 0)
   {
    flag = 1;
    cur += 10;
   }
   tmp[sizet - 1 - i] = cur + '0';
 
   pData1[size1 - 2 - i] -= flag;
 
  }
  return BigData(tmp);
 }
}
 
 
BigData BigData:: operator*(const BigData bigdata)
{
 //1、都在INT64范围内<运算后在范围内,运算后不在范围内>
 //   同号与 MAX_DATA比较  异号与MIN_DATA比较
 //2、至少一个不在范围内
 if (0 == _value || 0 == bigdata._value)
 {
  return BigData(0);
 }
 if (!PDataIsOverINT64() && !bigdata.PDataIsOverINT64())
 {
  if (_pData[0]==bigdata._pData[0])//同号
  {
   if (_value >= 0)//为正
   {
    if (_value < MAX_INT64 / bigdata._value)//结果在范围内
    {
     return BigData(_value*bigdata._value);
    }
    else // 结果不在范围内
    {
     return Mul(_pData,bigdata._pData);
    }
   }
   else//为负
   {
    if (_value > MAX_INT64 / bigdata._value)//结果在范围内
    {
     return BigData(_value*bigdata._value);
    }
    else // 结果不在范围内
    {
     return Mul(_pData, bigdata._pData);
    }
   }
  }
  else  //异号
  {
   if (_value >= 0)//为正 负
   {
    if (_value < MIN_INT64 / bigdata._value)//结果在范围内
    {
     return BigData(_value*bigdata._value);
    }
    else // 结果不在范围内
    {
     return Mul(_pData, bigdata._pData);
    }
   }
   else //为 负 正
   {
    if (_value > MIN_INT64 / bigdata._value)//结果在范围内
    {
     return BigData(_value*bigdata._value);
    }
    else // 结果不在范围内
    {
     return Mul(_pData, bigdata._pData);
    }
   }
  }
 }
 else
 {
  return Mul(_pData, bigdata._pData);
 }
}
 
BigData BigData::Mul(string pData1, string pData2)
{
 //同号 异号  先大数 后小数  
 //为提高效率 外层循环次数少,内层次数多
 
 std::string tmp;
 int size1 = pData1.size();
 int size2 = pData2.size();
 int sizet = size1 + size2;
 tmp.resize(size1 + size2);
 tmp[0] = '+';
 if (pData1[0] != pData2[0])//同号 异号 
 {
  tmp[0] = '-';
 }
 
 if (size1 < size2 || (size1 == size2&&strcmp(&pData1[0], pData2.c_str()) < 0))//先大数 后小数
 {
  swap(pData1, pData2);
  swap(size1, size2);
 }
 
 _EachSub0(pData1);
 _EachSub0(pData2);
 //tmp初始化时 全为 0
 for (int i = 1; i < size2; i++)//小数位数  
 {
  if (pData2[size2 - i] == 0)  //若位数上为0则跳过
  {
   continue;
  }
  for (int j = 1; j < size1; j++)//大数位数
  {
   if (pData1[size1 - j] == 0)  //若位数上为0则跳过
   {
    continue;
   }
   tmp[sizet - j - i + 1] += pData1[size1 - j] * pData2[size2 - i];
   if (tmp[sizet - j - i + 1]>=10)
   {
    tmp[sizet - j - i] += tmp[sizet - j - i + 1] / 10;
    tmp[sizet - j - i + 1] %= 10;
   }
  }
 
 }
 
 for (int i = 0; i < sizet - 1; i++)
 {
  if (tmp[sizet - i - 1] >= 10)
  {
   tmp[sizet - i - 2] += tmp[sizet - i - 1] / 10;
   tmp[sizet - i - 1] %= 10;
  }
 }
 
 _EachAdd0(tmp);
 return BigData(tmp);
}
 
BigData BigData:: operator/(const BigData bigdata)
{
 //1、排除除数为0
 //2、在范围内,不在范围内
 //3、不在范围内<左(被除数)比右(除数)小为0,左比右大>
 //4、正负
 
 if (0 == bigdata._value)
 {
  assert(false);
 }
 
 if (!PDataIsOverINT64() && !bigdata.PDataIsOverINT64())
 {
  return BigData(_value / bigdata._value);
 }
 else
 {
  //左(被除数)比右(除数)小为0
  if (_pData.size() < bigdata._pData.size() ||
   (_pData.size() == bigdata._pData.size() && _pData[0] == bigdata._pData[0]&&
   strcmp((char*)&_pData[0],(char*)&bigdata._pData[0]) < 0))
  {
   return BigData(0);//正0 负0 都记为0 
  }
  else //左比右大
  {
   return Div(_pData, bigdata._pData);
  }
 }
}
 
 
 
BigData BigData::Div(string pData1, string pData2)
{
 //正负且 参数左大右小
 char* _trueDiv(char* tp1, char* tmp2, int size, string& cur);
 
 string cur;
 cur.append(1, '+');
 if (pData1[0] != pData2[0])
 {
  cur[0] = '-';
 }
 
// char* tmp1 = (char*)malloc(pData1.size());// *tmp2 = (char*)malloc(pData2.size());
 char* tmp1 = new char [pData1.size()];
 strcpy(tmp1, &pData1[1]); //strcpy内部实现free(tmp1)
 char*tmp2 = &pData2[1];
 int size2 = strlen(tmp2);
 int sizermd = size2;
 int excursion = size2;
 char* rmd = NULL;
 
 while (strlen(tmp1) > strlen(tmp2) || 
  (strlen(tmp1) == strlen(tmp2) && strcmp(tmp1, tmp2) > 0))//左大于右时,循环
 {  
  while (sizermd < size2 || (sizermd == size2&&strncmp(tmp1, tmp2, sizermd)<0))//不够 商0
  {
   cur.append(1, '0');
   sizermd++;
   ++excursion;
  }
 
  rmd = _trueDiv(tmp1, tmp2, sizermd, cur);// 16713  31071  
  sizermd = strlen(rmd);
   
  strcat(rmd, &pData1[++excursion]);
 
  tmp1 = rmd;
  sizermd++;  // 将余数与剩余被除数相接
 }
 
 return BigData(cur);
}
 
char* _trueDiv(char* tp1, char* tp2, int size1, string& cur)
{
 //只有tp1和 tp2位数相同且比tp2大,或者比tp2多一位的情况
 int size2 = strlen(tp2);
 
 int i = 0;
 tp1[size1] = '\0';
 
 char count = 0;
 int flag = 0;
 
 while (size1 > size2 ||
  (size1 == size2&&strcmp(tp1, tp2) > 0))//tp1大于tp2
 {
  for (i = 0; i < size1; i++)
  {
   flag = 0;
   int count = 0;
   if (i < size2)
   {
    count = tp1[size1 - i - 1] - tp2[size2 - i - 1];
   }
   else
   {
    count = tp1[size1 - i - 1] - '0';
   }
   if (count < 0)
   {
    flag = 1;
    count += 10;
   }
   tp1[size1 - 1 - i] = count + '0';
 
   tp1[size1 - 2 - i] -= flag;
 
   while (*tp1 == '0' && size1>1)//可能出现整除情况
   {
    tp1++;
    size1--;
   }
 
  }
  count++;
 }
 
 cur.append(1, count + '0');
 return tp1;
}
 
void test()
{
 BigData b0(13215156);
 BigData b10(-13215156);
 BigData b11(9787687678661325156);//当传入的数值大于MAX_DATA且位数相等时,编译器不能检测,导致由正转负
 BigData b12(-9223372036854775807);
 BigData b1("a13215jfiow");
 b1.Print();
 cout << b1<< endl;
 BigData b2("+000023215");
 cout << b2 << endl;
 b2.Print();
 BigData b3(" 33215jfiow"); //(Tab、空格键消除用isspace(int))
 cout << b3 << endl;
 b3.Print();
 BigData b4("    -33215jfiow");
 cout << b4 << endl;
 b4.Print();
 BigData b5("43215jfiow");
 b5.Print();
 cout << b5 << endl;
 
 //BigData b6("4321537537354373783783");
 //b6.Print(); 
 //cout << b6 << endl;
 BigData b7("-43215378338735373783537");
 cout << b7 << endl;
 b7.Print();
 BigData b8("-9223372036854775808");
 cout << b8 << endl;
 b8.Print();
 BigData b9("-999999");
 cout << b9 << endl;
 b9.Print();
 
 BigData b101("43215378338735373783537");
 BigData b102("-43215378338735373783537");
 BigData b103("-43215378338735373783537");
 BigData b110("-43215378338735373783537");
 
 (b2 + b9).Print();
 cout << (b2 + b9) << endl;
}
 
void testAdd()
{
 BigData b1("-45353");
 BigData b2("37353753");
 BigData b3("-9223372036854775808");
 BigData b4(" 9223372036854775800");
 BigData b5("-9223372036854775810");
 BigData b6(" 9223372036854775900");
 
 cout << (b1 + b1) << endl; 
 cout << (b2 + b2) << endl;
 cout << (b1 + b2) << endl;
 cout << (b1 + b4) << endl;
 
 cout << b3 << endl;
 cout << (b1 + b3) << endl;
 cout << (b2 + b4) << endl;
 
 cout << (b2 + b5) << endl;
 cout << (b1 + b6) << endl;
 cout << (b6 + b1) << endl;
 
}
 
void testSub()
{
 BigData b1("-45353");
 BigData b2("37353753");
 BigData b3("-9223372036854775808");
 BigData b4(" 9223372036854775800");
 BigData b5("-9223372036854775810");
 BigData b6(" 9223372036854775900");
 
 cout << (b1 - b2) << endl;
 cout << (b2 - b1) << endl; 
 cout << (b3 - b1) << endl;
 cout << (b1 - b4) << endl;
 cout << (b3 - b2) << endl;
 cout << (b4 - b1) << endl;
 cout << (b1 - b3) << endl;
 cout << (b2 - b4) << endl;
 cout << endl;
 
 
 cout << (b5 - b1) << endl;
 cout << (b1 - b5) << endl;
 cout << endl;
 cout << (b6 - b2) << endl;
 cout << (b2 - b6) << endl;
 cout << endl;
 cout << (b6 - b5) << endl;
 cout << (b5 - b6) << endl;
 cout << (b2 - b5) << endl;
 cout << (b1 - b6) << endl;
 cout << (b6 - b1) << endl;
 
}
 
 
void testMul()
{
 BigData b1("-45353");
 BigData b2("37353753");
 BigData b3("-9223372036854775808");
 BigData b4(" 9223372036854775800");
 BigData b5("-9223372036854775810");
 BigData b6(" 9223372036854775900");
 
 cout << (BigData("999") * BigData("22222222222222222222222222222")) << endl;
 
 cout << (b2 * b1) << endl;
 cout << (b1 * b2) << endl;
 cout << (b1 * BigData(0)) << endl;
 cout << (BigData(0) * b2) << endl;
 cout << endl;
 cout << (b3 * b1) << endl;
 cout << (b1 * b3) << endl;
 cout << (b1 * b4) << endl;
 cout << (b4 * b1) << endl;
 cout << (b3 * b2) << endl;
 cout << (b2 * b4) << endl;
 cout << endl;
 
 
 cout << (BigData(0) * b6) << endl;
 cout << (b5 * BigData(0)) << endl;
 cout << (b5 * b1) << endl;
 cout << (b1* b5) << endl;
 cout << endl;
 cout << (b6 * b2) << endl;
 cout << (b2 * b6) << endl;
 cout << endl;
 cout << (b6 * b5) << endl;
 cout << (b5 * b6) << endl;
 cout << (b2 * b5) << endl;
 cout << endl;
 cout << (b1 * b6) << endl;
 cout << (b6 * b1) << endl;
 BigData b7("-203367738338252");
 cout << b7*b1 << endl;
}
 
 
void testDiv()
{
 BigData b1("-45353");
 BigData b2("37353753");
 BigData b3("-9223372036854775808");
 BigData b4(" 9223372036854775800");
 BigData b5("-9223372036854775810");
 BigData b6(" 9223372036854775900");
 BigData b7("-1231123203367738338252");
 
 
 //1、排除除数为0
 //cout << (b1 / BigData(0)) << endl;
 
 //2、在范围内
 
 cout << (b1 / b2) << endl;
 cout << (b2 / b1) << endl;
 
 
 //3、不在范围内<左(被除数)比右(除数)小为0,左比右大>
 cout << (b2 / b5) << endl;
 cout << (b2 / b6) << endl;
 
 cout << (b5 / b2) << endl;
 cout << (b6 / b2) << endl;
 cout << (b6 / b1) << endl;
 cout << (b5 / b1) << endl;
 
 cout << b7 / b1 << endl;
}
 
int main()
{
 //testAdd();
 //testSub();
 //testMul();
 testDiv();
  return 0;
}