#pragma once
using namespace std;
#include <iostream>
#include <string.h>
class BigNum
{
private:
char *x = new char[40001];
//char x[40001];
public:
BigNum()
{
x[0] = '+';
for (int i = 1; i < 40001; i++)x[i] = 0;
}
BigNum(const BigNum &B)
{
int count = 0;
int str = strlen(B.x);
cout << "copy\n";
while (B.x[1 + count] == 48 && str != count + 2/*||(str!=count+3&&B.x[count+1]!=48)*/)
{
count++;
}
x[0] = B.x[0];
//if (str == count + 3 && B.x[count + 1] == 48)this->x[0]='+';
strncpy(x + 1, B.x + count + 1, 40000);
}
~BigNum()
{
delete[] x;
}
friend int compare(BigNum & A, BigNum &B);
friend istream & operator >> (istream &, BigNum &);
friend ostream & operator << (ostream &, const BigNum &);
friend BigNum operator +(BigNum A2, BigNum B2);
friend BigNum operator -(BigNum A2, BigNum B2);
friend BigNum operator *(BigNum A2, BigNum B2);
friend BigNum operator /(BigNum A2, BigNum B2);
const BigNum &operator =(const BigNum & B)
{
int count = 0;
int str = strlen(B.x);
while (B.x[1 + count] == 48 && str != count + 2)//||(str!=count+3&&B.x[count+1]!=48))
{
count++;
}
x[0] = B.x[0];
//if (str == count + 3 && B.x[count + 1] == 48)this->x[0]='+';
strncpy(x + 1, B.x + count + 1, 40000);
return *this;
};
};
int compare(BigNum & A, BigNum &B)
{
int count = 1;
while (A.x[count] == 48)count++;
count = 1;
while (B.x[0] == 48)count++;
int s = strlen(A.x + count), t = strlen(B.x + count);
if (s - t < 0)return 1;
if (s - t == 0)for (int i = 1; i < s + 1; i++)
{
if (A.x[i] > B.x[i])return 0;
if (A.x[i] < B.x[i])return 1;
}
return 0;
}
istream & operator >> (istream & str, BigNum & obj)
{
str >> obj.x + 1;
//scanf("%s", obj.x+1);
//fgets(obj.x, 4097, stdin);
// for (int i = 1; i < 4100; i++)//scanf("%c", &obj.x[i]);
//str.get(obj.x[i]);
int len = strlen(obj.x + 1);
if (obj.x[1] == '-' || obj.x[1] == '+')
{
for (int i = 0; i < len; i++)
{
obj.x[i] = obj.x[i + 1];
}
obj.x[len] = 0;
}
return str;
}
ostream & operator << (ostream & str, const BigNum & obj)
{
if ((obj.x[1] == '0'&&obj.x[0] == '-') || obj.x[0] == '+')str << obj.x + 1;
else str << obj.x;
return str;
}
BigNum operator +(BigNum A2, BigNum B2)
{
BigNum temp;
if (A2.x[0] == '+'&&B2.x[0] == '-')//+-
{
B2.x[0] = '+';
return A2 - B2;
}
else if (A2.x[0] == '-'&&B2.x[0] == '+')//-+
{
A2.x[0] = '+';
return B2 - A2;
}
int str1 = strlen(A2.x), str2 = strlen(B2.x);
int gap = str1 - str2;
if (str2 > str1)
{
int temp2;
temp = A2;
A2 = B2;
B2 = temp;
temp2 = str1;
str1 = str2;
str2 = temp2;
gap = gap*(-1);
}
if (A2.x[0] == '-'&&B2.x[0] == '-')temp.x[0] = '-';
temp.x[1] = 48;
strncpy(temp.x + 2, A2.x + 1, str1 + 1);
for (int i = str1 - 1; i > gap; i--)
temp.x[i + 1] = temp.x[i + 1] + B2.x[i - gap] - 48;
for (int i = str1 - 1; i >= 1; i--)
if (temp.x[i + 1] > 57)
{
temp.x[i + 1] = temp.x[i + 1] - 10;
temp.x[i]++;
}
return temp;
}
BigNum operator -(BigNum A2, BigNum B2)
{
BigNum temp;
if (A2.x[0] == '+'&&B2.x[0] == '-')
{
B2.x[0] = '+';
return A2 + B2;
}
else if (A2.x[0] == '-'&&B2.x[0] == '+')
{
B2.x[0] = '-';
return A2 + B2;
}
int str1 = strlen(A2.x), str2 = strlen(B2.x);
int gap = str1 - str2;
if (str2 > str1 || compare(A2, B2))
{
int temp2;
temp = A2;
A2 = B2;
B2 = temp;
temp2 = str1;
str1 = str2;
str2 = temp2;
gap = gap*(-1);
if (A2.x[0] == '+'&&B2.x[0] == '+')temp.x[0] = '-';
else temp.x[0] = '+';
}
else if (A2.x[0] == '-'&&B2.x[0] == '-')temp.x[0] = '-';
else temp.x[0] = '+';
strncpy(temp.x + 1, A2.x + 1, str1);
for (int i = gap + 1; i < str1; i++)
{
if (temp.x[i] >= B2.x[i - gap])temp.x[i] = temp.x[i] - B2.x[i - gap] + 48;
else
{
temp.x[i] = temp.x[i] - B2.x[i - gap] + 58;
for (int j = i - 1; j >= 0; j--)
if (temp.x[j] > 48)
{
temp.x[j]--;
for (int k = j + 1; k < i; k++)
{
temp.x[k] = temp.x[k] + 9;
}
break;
}
}
}
return temp;
}
BigNum operator *(BigNum A2, BigNum B2)
{
int str1 = strlen(A2.x), str2 = strlen(B2.x);
int gap = str1 - str2;
static int mul[40001];
BigNum temp;
if (str2 > str1)
{
int temp2;
temp = A2;
A2 = B2;
B2 = temp;
temp2 = str1;
str1 = str2;
str2 = temp2;
gap = gap*(-1);
}
if ((A2.x[0] == '-') ^ (B2.x[0] == '-'))temp.x[0] = '-';
else temp.x[0] = '+';
for (int i = 0; i < 40001; i++)mul[i] = 48;
mul[str1 + str2] = 0;
temp.x[str1 + str2] = 0;
for (int i = 1; i < str1; i++)
for (int j = 1; j < str2; j++)//函數乘法
mul[i + j + 1] = mul[i + j + 1] + (A2.x[i] - 48) * (B2.x[j] - 48);
for (int i = str1 + str2 - 1; i >= 1; i--)
if (mul[i + 1] > 57)
{
mul[i] = mul[i] + (mul[i + 1] - 48) / 10;
mul[i + 1] = (mul[i + 1] - 48) % 10 + 48;
}
for (int i = 1; i < str1 + str2; i++)temp.x[i] = (char)mul[i];
return temp;
}
BigNum operator /(BigNum A2, BigNum B2)
{
int str1 = strlen(A2.x), str2 = strlen(B2.x);
int gap = str1 - str2;
BigNum temp;
temp.x[1] = '0';
if (str2 > str1 || compare(A2, B2))return temp;
if ((A2.x[0] == '-') ^ (B2.x[0] == '-'))temp.x[0] = '-';
else temp.x[0] = '+';
A2.x[0] = B2.x[0] = '+';
BigNum temp2 = A2;
for (int i = 1; i <= gap; i++)
{
B2.x[str2 + i - 1] = 48;
B2.x[str2 + i] = 0;
}
for (int j = 1; j < gap + 2; j++)
{
if (compare(temp2, B2) == 1)
{
temp.x[j] = 48;
}
else for (int i = 1; i < 10; i++)
{
temp2 = temp2 - B2;
if (compare(temp2, B2) != 1)continue;//1小0大
else
{
temp.x[j] = i + 48;
break;
}
}
B2.x[str1 - j] = 0;
}
return temp;
}