您的位置:首页 > 其它

高精度整数运算改进版

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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: