高精度整数运算改进版
2013-06-10 12:27
483 查看
#include<iostream>
#include<string>
using namespace std;
const unsigned int MAX = 10000; //整型数组的最大长度
const long long WIDTHMAX = 1000000000; //整型数组val[MAX]的元素上限
const unsigned int WIDTH = 9;
//输出整型数组val[MAX]的元素时的格式宽度,即整型数组val[MAX]的元素的最多位数
typedef struct node
{
long long val[MAX]; //用来存储高精度整数
unsigned int size; //整型数组的实际长度
} BigInt;
BigInt StrToBigInt(string s);
void PrintBigInt(const BigInt & a);
int ComPareBigInt(const BigInt & a, const BigInt
& b);
BigInt MulBigInt(const BigInt & a, const BigInt
& b);
BigInt AddBigInt(const BigInt & a, const BigInt
& b);
BigInt SubBigInt(BigInt a, BigInt b);
BigInt DivBigInt(const BigInt & a, const BigInt
& b);
BigInt FacBigInt(unsigned int n);
void PowBigInt(BigInt & c, const BigInt
& a, unsigned int n);
void PowBigInt_2(BigInt & c, const BigInt
& a, unsigned int n);
BigInt HalfBigInt(BigInt a);
int main()
{
string s;
BigInt a, b, c;
cin >> s;
a = StrToBigInt(s);
cin >> s;
b = StrToBigInt(s);
cout << " ";
PrintBigInt(a);
cout << "+ ";
PrintBigInt(b);
c = AddBigInt(a, b);
cout << "= ";
PrintBigInt(c);
cout << endl;
cout << " ";
PrintBigInt(a);
cout << "- ";
PrintBigInt(b);
c = SubBigInt(a, b);
cout << "= ";
PrintBigInt(c);
cout << endl;
cout << " ";
PrintBigInt(a);
cout << "* ";
PrintBigInt(b);
c = MulBigInt(a, b);
cout << "= ";
PrintBigInt(c);
cout << endl;
cout << " ";
PrintBigInt(a);
cout << "/ 2 "
<< endl;
c = HalfBigInt(a);
cout << "= ";
PrintBigInt(c);
cout << endl;
cout << " ";
PrintBigInt(a);
cout << "/ ";
PrintBigInt(b);
c = DivBigInt(a, b);
cout << "= ";
PrintBigInt(c);
cout << endl;
unsigned int n;
cin >> n;
//cout << n
<< "! = ";
// c = FacBigInt(n);
// PrintBigInt(c);
// cout << c.size
<< endl;
cout << endl;
cout << " ";
PrintBigInt(a);
cout << "^"
<< n <<
" = ";
PowBigInt(c, a, n);
PrintBigInt(c);
cout << endl;
cout << " ";
PrintBigInt(a);
cout << "^"
<< n <<
" = ";
PowBigInt_2(c, a, n);
PrintBigInt(c);
cout << endl;
system("pause");
return 0;
}
void PrintBigInt(const BigInt & a)
{
cout << a.val[a.size-1];
for (int i=a.size-2; i>=0; i--)
{
unsigned w = WIDTHMAX / 10;
while (w > 0)
{
if (a.val[i] >= w)
break;
cout << 0;
w /= 10;
}
cout << a.val[i];
}
cout << endl;
}
BigInt StrToBigInt(string s)
{
BigInt a;
a.size = 0;
int i = s.size();
unsigned long long sum = 0;
while ( i>=WIDTH)
{
for (int j=i-WIDTH; j<i; j++)
sum = sum * 10 + (s[j] - '0');
a.val[a.size++] = sum;
sum = 0;
i -= WIDTH;
}
if (i > 0)
{
for (int j=0; j<i; j++)
sum = sum * 10 + (s[j] - '0');
a.val[a.size++] = sum;
}
return a;
}
BigInt AddBigInt(const BigInt & a, const BigInt
& b)
{
//逆序计算a+b,则从低位开始计算
BigInt c;
unsigned long long carry = 0;
unsigned int i = 0;
c.size = 0;
while (i < a.size &&
i < b.size)
{
c.val[c.size++] = (a.val[i] + b.val[i] + carry) % WIDTHMAX;
carry = (a.val[i] + b.val[i] + carry) / WIDTHMAX;
i++;
}
while (i < a.size)
{
c.val[c.size++] = (a.val[i] + carry) % WIDTHMAX;
carry = (a.val[i] + carry) / WIDTHMAX;
i++;
}
while (i < b.size)
{
c.val[c.size++] = (b.val[i] + carry) % WIDTHMAX;
carry = (b.val[i] + carry) / WIDTHMAX;
i++;
}
if (carry > 0)
c.val[c.size++] = carry;
return c;
}
BigInt SubBigInt(BigInt a, BigInt b)
{
BigInt c;
c.size = 0;
if (ComPareBigInt(a, b) == 0)
{
c.size = 1;
c.val[0] = 0;
return c;
}
bool flag = false;
if (ComPareBigInt(a, b) < 0)//交换,并得到一个负号
{
flag = true;
BigInt temp = a;
a = b;
b = temp;
}
unsigned int i = 0;
while (i < b.size)
{
if (a.val[i] >= b.val[i])
c.val[c.size++] = a.val[i] - b.val[i];
else
{
a.val[i+1] -= 1;
c.val[c.size++] = a.val[i] + WIDTHMAX - b.val[i];
}
i++;
}
while (i < a.size)
{
if (a.val[i] < 0)
{
a.val[i+1] -= 1;
a.val[i] += WIDTHMAX;
}
c.val[c.size++] = a.val[i];
i++;
}
//消除多余的高位0
while (c.val[c.size-1] == 0)
c.size--;
if (flag)//如果是负数,加上负号
c.val[c.size-1] = -c.val[c.size-1];
return c;
}
int ComPareBigInt(const BigInt & a, const BigInt
& b)
{
if (a.size > b.size)
return 1;
if (a.size < b.size)
return -1;
for (int i=a.size-1; i>=0; i--)
{
if (a.val[i] > b.val[i])
return 1;
if (a.val[i] < b.val[i])
return -1;
}
return 0;
}
BigInt MulBigInt(const BigInt & a, const BigInt
& b)
{
if (a.size == 1 && a.val[0] ==
0)
return a;
if (b.size == 1 && b.val[0] ==
0)
return b;
BigInt c;
for (int i=0; i<MAX; i++) //全部赋初值为0
c.val[i] = 0;
for (int i=0, j=0; i<b.size; i++)
{
for (j=0; j<a.size; j++)
{
c.val[i+j] += a.val[j] * b.val[i];
c.val[i+j+1] += c.val[i+j] / WIDTHMAX;
c.val[i+j] %= WIDTHMAX;
}
c.size = i + j;
if (c.val[c.size] != 0)//最高位有进位
c.size++;
}
return c;
}
BigInt FacBigInt(unsigned int n)
{
BigInt s, c;
c.size = s.size = 1;
s.val[0] = 1;
for (unsigned long long i=2; i<=n; i++)
{
c.val[0] = i;
s = MulBigInt(s, c);
}
return s;
}
void PowBigInt(BigInt & c, const BigInt
& a, unsigned int n)
{
if (n == 1)
{
c = a;
return ;
}
if (n == 0 || (a.size == 1 &&
a.val[0] == 1))
{
c.size = c.val[0] = 1;
return ;
}
PowBigInt(c, a, n/2); //递归求高精度整数幂
c = MulBigInt(c, c); //a^n = a^(n/2)*a^(n/2)*f(a)
if (n % 2 == 1) //其中f(a) = 1(n%2==0)或f(a) = a(n%2==1)
c = MulBigInt(a, c);
}
void PowBigInt_2(BigInt & c, const BigInt
& a, unsigned int n)
{
int stack[MAX] = {0};
int top = 0;
while (n > 0) //利用一个栈来存储n的状态:奇数还是偶数
{
stack[top++] = n % 2;
n /= 2;
}
c.size = c.val[0] = 1;
for (int i=top-1; i>=0; i--)
{
c = MulBigInt(c, c); //a^n = a^(n/2)*a^(n/2)*f(a)
if (stack[i] == 1) //其中f(a) = 1(n%2==0)或f(a) = a(n%2==1)
c = MulBigInt(a, c);
}
}
BigInt DivBigInt(const BigInt & a, const BigInt
& b)
{
BigInt high, low, mid, one, c;
if ((a.size == 1 && a.val[0] == 0)
|| (b.size == 1 && b.val[0] ==
0))
{
c.size = 1;
c.val[0] = 0;
return c;
}
one.size = 1; //值为1的高精度整数
one.val[0] = 1;
high = a; //上界
low.size = 1; //下界
low.val[0] = 0;
while (ComPareBigInt(low, high) < 0)
{
mid = HalfBigInt(AddBigInt(high, low)); //中间数
c = MulBigInt(mid, b);
if (ComPareBigInt(c, a) == 0)
return mid;
else if (ComPareBigInt(c, a) < 0)
low = AddBigInt(mid, one);
else
high = SubBigInt(mid, one);
}
c = MulBigInt(low, b);
if (ComPareBigInt(c, a) <= 0)
return low;
else
return SubBigInt(low, one);
}
BigInt HalfBigInt(BigInt a)
{
BigInt c;
c.size = a.size;
for (int i=a.size-1; i>0; i--)
{
c.val[i] = a.val[i] / 2;
if (a.val[i] % 2 == 1)
a.val[i-1] += WIDTHMAX;
}
c.val[0] = a.val[0] / 2;
if (c.size > 0 &&
c.val[c.size-1] == 0)
c.size--;
return c;
}
#include<string>
using namespace std;
const unsigned int MAX = 10000; //整型数组的最大长度
const long long WIDTHMAX = 1000000000; //整型数组val[MAX]的元素上限
const unsigned int WIDTH = 9;
//输出整型数组val[MAX]的元素时的格式宽度,即整型数组val[MAX]的元素的最多位数
typedef struct node
{
long long val[MAX]; //用来存储高精度整数
unsigned int size; //整型数组的实际长度
} BigInt;
BigInt StrToBigInt(string s);
void PrintBigInt(const BigInt & a);
int ComPareBigInt(const BigInt & a, const BigInt
& b);
BigInt MulBigInt(const BigInt & a, const BigInt
& b);
BigInt AddBigInt(const BigInt & a, const BigInt
& b);
BigInt SubBigInt(BigInt a, BigInt b);
BigInt DivBigInt(const BigInt & a, const BigInt
& b);
BigInt FacBigInt(unsigned int n);
void PowBigInt(BigInt & c, const BigInt
& a, unsigned int n);
void PowBigInt_2(BigInt & c, const BigInt
& a, unsigned int n);
BigInt HalfBigInt(BigInt a);
int main()
{
string s;
BigInt a, b, c;
cin >> s;
a = StrToBigInt(s);
cin >> s;
b = StrToBigInt(s);
cout << " ";
PrintBigInt(a);
cout << "+ ";
PrintBigInt(b);
c = AddBigInt(a, b);
cout << "= ";
PrintBigInt(c);
cout << endl;
cout << " ";
PrintBigInt(a);
cout << "- ";
PrintBigInt(b);
c = SubBigInt(a, b);
cout << "= ";
PrintBigInt(c);
cout << endl;
cout << " ";
PrintBigInt(a);
cout << "* ";
PrintBigInt(b);
c = MulBigInt(a, b);
cout << "= ";
PrintBigInt(c);
cout << endl;
cout << " ";
PrintBigInt(a);
cout << "/ 2 "
<< endl;
c = HalfBigInt(a);
cout << "= ";
PrintBigInt(c);
cout << endl;
cout << " ";
PrintBigInt(a);
cout << "/ ";
PrintBigInt(b);
c = DivBigInt(a, b);
cout << "= ";
PrintBigInt(c);
cout << endl;
unsigned int n;
cin >> n;
//cout << n
<< "! = ";
// c = FacBigInt(n);
// PrintBigInt(c);
// cout << c.size
<< endl;
cout << endl;
cout << " ";
PrintBigInt(a);
cout << "^"
<< n <<
" = ";
PowBigInt(c, a, n);
PrintBigInt(c);
cout << endl;
cout << " ";
PrintBigInt(a);
cout << "^"
<< n <<
" = ";
PowBigInt_2(c, a, n);
PrintBigInt(c);
cout << endl;
system("pause");
return 0;
}
void PrintBigInt(const BigInt & a)
{
cout << a.val[a.size-1];
for (int i=a.size-2; i>=0; i--)
{
unsigned w = WIDTHMAX / 10;
while (w > 0)
{
if (a.val[i] >= w)
break;
cout << 0;
w /= 10;
}
cout << a.val[i];
}
cout << endl;
}
BigInt StrToBigInt(string s)
{
BigInt a;
a.size = 0;
int i = s.size();
unsigned long long sum = 0;
while ( i>=WIDTH)
{
for (int j=i-WIDTH; j<i; j++)
sum = sum * 10 + (s[j] - '0');
a.val[a.size++] = sum;
sum = 0;
i -= WIDTH;
}
if (i > 0)
{
for (int j=0; j<i; j++)
sum = sum * 10 + (s[j] - '0');
a.val[a.size++] = sum;
}
return a;
}
BigInt AddBigInt(const BigInt & a, const BigInt
& b)
{
//逆序计算a+b,则从低位开始计算
BigInt c;
unsigned long long carry = 0;
unsigned int i = 0;
c.size = 0;
while (i < a.size &&
i < b.size)
{
c.val[c.size++] = (a.val[i] + b.val[i] + carry) % WIDTHMAX;
carry = (a.val[i] + b.val[i] + carry) / WIDTHMAX;
i++;
}
while (i < a.size)
{
c.val[c.size++] = (a.val[i] + carry) % WIDTHMAX;
carry = (a.val[i] + carry) / WIDTHMAX;
i++;
}
while (i < b.size)
{
c.val[c.size++] = (b.val[i] + carry) % WIDTHMAX;
carry = (b.val[i] + carry) / WIDTHMAX;
i++;
}
if (carry > 0)
c.val[c.size++] = carry;
return c;
}
BigInt SubBigInt(BigInt a, BigInt b)
{
BigInt c;
c.size = 0;
if (ComPareBigInt(a, b) == 0)
{
c.size = 1;
c.val[0] = 0;
return c;
}
bool flag = false;
if (ComPareBigInt(a, b) < 0)//交换,并得到一个负号
{
flag = true;
BigInt temp = a;
a = b;
b = temp;
}
unsigned int i = 0;
while (i < b.size)
{
if (a.val[i] >= b.val[i])
c.val[c.size++] = a.val[i] - b.val[i];
else
{
a.val[i+1] -= 1;
c.val[c.size++] = a.val[i] + WIDTHMAX - b.val[i];
}
i++;
}
while (i < a.size)
{
if (a.val[i] < 0)
{
a.val[i+1] -= 1;
a.val[i] += WIDTHMAX;
}
c.val[c.size++] = a.val[i];
i++;
}
//消除多余的高位0
while (c.val[c.size-1] == 0)
c.size--;
if (flag)//如果是负数,加上负号
c.val[c.size-1] = -c.val[c.size-1];
return c;
}
int ComPareBigInt(const BigInt & a, const BigInt
& b)
{
if (a.size > b.size)
return 1;
if (a.size < b.size)
return -1;
for (int i=a.size-1; i>=0; i--)
{
if (a.val[i] > b.val[i])
return 1;
if (a.val[i] < b.val[i])
return -1;
}
return 0;
}
BigInt MulBigInt(const BigInt & a, const BigInt
& b)
{
if (a.size == 1 && a.val[0] ==
0)
return a;
if (b.size == 1 && b.val[0] ==
0)
return b;
BigInt c;
for (int i=0; i<MAX; i++) //全部赋初值为0
c.val[i] = 0;
for (int i=0, j=0; i<b.size; i++)
{
for (j=0; j<a.size; j++)
{
c.val[i+j] += a.val[j] * b.val[i];
c.val[i+j+1] += c.val[i+j] / WIDTHMAX;
c.val[i+j] %= WIDTHMAX;
}
c.size = i + j;
if (c.val[c.size] != 0)//最高位有进位
c.size++;
}
return c;
}
BigInt FacBigInt(unsigned int n)
{
BigInt s, c;
c.size = s.size = 1;
s.val[0] = 1;
for (unsigned long long i=2; i<=n; i++)
{
c.val[0] = i;
s = MulBigInt(s, c);
}
return s;
}
void PowBigInt(BigInt & c, const BigInt
& a, unsigned int n)
{
if (n == 1)
{
c = a;
return ;
}
if (n == 0 || (a.size == 1 &&
a.val[0] == 1))
{
c.size = c.val[0] = 1;
return ;
}
PowBigInt(c, a, n/2); //递归求高精度整数幂
c = MulBigInt(c, c); //a^n = a^(n/2)*a^(n/2)*f(a)
if (n % 2 == 1) //其中f(a) = 1(n%2==0)或f(a) = a(n%2==1)
c = MulBigInt(a, c);
}
void PowBigInt_2(BigInt & c, const BigInt
& a, unsigned int n)
{
int stack[MAX] = {0};
int top = 0;
while (n > 0) //利用一个栈来存储n的状态:奇数还是偶数
{
stack[top++] = n % 2;
n /= 2;
}
c.size = c.val[0] = 1;
for (int i=top-1; i>=0; i--)
{
c = MulBigInt(c, c); //a^n = a^(n/2)*a^(n/2)*f(a)
if (stack[i] == 1) //其中f(a) = 1(n%2==0)或f(a) = a(n%2==1)
c = MulBigInt(a, c);
}
}
BigInt DivBigInt(const BigInt & a, const BigInt
& b)
{
BigInt high, low, mid, one, c;
if ((a.size == 1 && a.val[0] == 0)
|| (b.size == 1 && b.val[0] ==
0))
{
c.size = 1;
c.val[0] = 0;
return c;
}
one.size = 1; //值为1的高精度整数
one.val[0] = 1;
high = a; //上界
low.size = 1; //下界
low.val[0] = 0;
while (ComPareBigInt(low, high) < 0)
{
mid = HalfBigInt(AddBigInt(high, low)); //中间数
c = MulBigInt(mid, b);
if (ComPareBigInt(c, a) == 0)
return mid;
else if (ComPareBigInt(c, a) < 0)
low = AddBigInt(mid, one);
else
high = SubBigInt(mid, one);
}
c = MulBigInt(low, b);
if (ComPareBigInt(c, a) <= 0)
return low;
else
return SubBigInt(low, one);
}
BigInt HalfBigInt(BigInt a)
{
BigInt c;
c.size = a.size;
for (int i=a.size-1; i>0; i--)
{
c.val[i] = a.val[i] / 2;
if (a.val[i] % 2 == 1)
a.val[i-1] += WIDTHMAX;
}
c.val[0] = a.val[0] / 2;
if (c.size > 0 &&
c.val[c.size-1] == 0)
c.size--;
return c;
}
相关文章推荐
- 高精度整数运算改进版
- 高精度整数运算改进版(转)
- 高精度整数运算改进版
- 高精度运算总结(10.21更新整数乘法)
- 实用算法实现-第 24 篇 高精度整数运算
- 实用算法实现-第 24 篇 高精度整数运算
- 高精度整数运算
- 大整数运算(高精度运算)
- 大整数运算||高精度运算
- [算法设计与分析]3.2.4大整数存储及运算(高精度*长整数+n!)
- 高精度整数运算
- c语言高精度大整数加法运算
- 正整数高精度运算
- 整数高精度运算的库(加法,减法,乘法,除法,取模)
- Java编程--RSA算法中的大整数运算
- 程序员面试(1):利用位运算完成两个整数的加法运算
- 使用C++的string实现高精度加法运算
- linux shell 实现 四则运算(整数及浮点) 简单方法
- 大精度整数三种运算(加法,减法,乘法)
- 巨型整数的运算(绝对原创)