#include <stdio.h>
#include <math.h>
#include <iostream>
using namespace std;
class decnum
{
friend decnum pow(const decnum& x, int n);
friend decnum root(const decnum& x, int n);
friend decnum div(const decnum& x, const decnum& y, decnum& r);
friend decnum abs(const decnum& x);
friend bool operator==(const decnum& x, const decnum&y);
friend bool operator!=(const decnum& x, const decnum&y);
friend bool operator>(const decnum& x, const decnum&y);
friend bool operator<(const decnum& x, const decnum&y);
friend bool operator>=(const decnum& x, const decnum&y);
friend bool operator<=(const decnum& x, const decnum&y);
friend ostream& operator<<(ostream&os, const decnum& x);
public:
decnum() : cap(0), num(0), sign(0), val(NULL) { }
decnum(const char *v, int n)
{
int i, j,k;
val = new char[n];
if(v[0] == '-')
{
sign = 1;
v++;
n--;
}
else
{
sign = 0;
if(v[0] == '+')
v++;
}
for(i = 0; i < n && v[i] == '0'; i++);
for (j=0,k=n-1;k>=i;--k,++j)
{
if (v[k]>='0' && v[k]<='9')
{
val[j] = v[k]-'0';
}
else
break;
}
num = j;
cap = n;
}
decnum(const decnum& x)
{
val = new char[x.num];
memcpy(val, x.val, x.num);
sign = x.sign;
num = x.num;
cap = x.num;
}
decnum(int x)
{
if(x==0)
{
cap = num = 0;
val = NULL;
return;
}
if(x < 0)
{
sign = 1;
x = -x;
}
else
sign = 0;
char temp[20];
sprintf(temp, "%d", x);
int n = strlen(temp);
num = cap = n;
val = new char[n];
for(int i=0; i<n; i++)
val[i] = temp[n-1-i] - '0';
}
decnum(long long x)
{
if(x==0)
{
cap = num = 0;
val = NULL;
return;
}
if(x < 0)
{
sign = 1;
x = -x;
}
else
sign = 0;
char temp[20];
sprintf(temp, "%lld", x);
int n = strlen(temp);
num = cap = n;
val = new char[n];
for(int i=0; i<n; i++)
val[i] = temp[n-1-i] - '0';
}
~decnum() { delete[] val; }
int size() const { return num; }
decnum& operator=(const decnum& x)
{
if (this != &x)
{
if(cap < x.num)
{
delete[] val;
val = new char[x.num];
cap = x.num;
}
memcpy(val, x.val, x.num);
num = x.num;
sign = x.sign;
}
return *this;
}
decnum& operator=(int x)
{
*this = decnum(x);
return *this;
}
decnum& operator=(long long x)
{
*this = decnum(x);
return *this;
}
decnum& abs()
{
sign = 0;
return *this;
}
decnum& operator+=(const decnum& x);
decnum& operator-=(const decnum& x);
decnum& operator*=(const decnum& x);
decnum& operator/=(const decnum& x);
decnum& operator%=(const decnum& x);
decnum operator+(const decnum& x) const;
decnum operator-(const decnum& x) const;
decnum operator*(const decnum& x) const;
decnum operator/(const decnum& x) const;
decnum operator%(const decnum& x) const;
bool ispow(int n, decnum& r) const;
bool ispow() const;
private:
int cap;
int num;
int sign;
char *val;
private:
char root_1(int n);
decnum& absadd(const decnum& x);
decnum& abssub(const decnum& x);
bool absge(const decnum& x);
};
实现代码
大数类实现代码
#include "decnum.h"
decnum& decnum::absadd(const decnum& x)
{
int i, max;
char carry = 0, ch;
if(x.num == 0) return *this;
if(num < x.num)
max = x.num + 1;
else
max = num + 1;
if(max > cap)
{
cap = max;
char *newval = new char[cap];
memcpy(newval, val, num);
memset(newval+num, 0, cap - num);
delete[] val;
val = newval;
}
else
{
memset(val+num, 0, max - num);
}
num = max-1;
for(i=0; i<x.num; i++)
{
ch = val[i] + x.val[i] + carry;
if(ch > 9)
{
carry = 1;
val[i] = ch - 10;
}
else
{
carry = 0;
val[i] = ch;
}
}
for(; i<=num && carry == 1; i++)
{
ch = val[i] + 1;
if(ch > 9)
{
carry = 1;
val[i] = ch - 10;
}
else
{
carry = 0;
val[i] = ch;
}
}
if(i>num) num = i;
return *this;
}
decnum& decnum::abssub(const decnum& x)
{
if(x.num == 0) return *this;
int i;
char carry = 0, ch;
for(i=0; i<x.num; i++)
{
ch = val[i] - x.val[i] - carry;
if(ch < 0)
{
carry = 1;
val[i] = ch + 10;
}
else
{
carry = 0;
val[i] = ch;
}
}
for(; i<num && carry == 1; i++)
{
ch = val[i] - 1;
if(ch < 0)
{
carry = 1;
val[i] = ch + 10;
}
else
{
carry = 0;
val[i] = ch;
}
}
for(i=num; i>0 && val[i-1] == 0; i--);
num = i;
return *this;
}
bool decnum::absge(const decnum& x)
{
if(num > x.num) return true;
if(num < x.num) return false;
for(int i=num-1; i >= 0; i--)
{
if(val[i] > x.val[i])
return true;
else if(val[i] < x.val[i])
return false;
}
return true;
}
decnum& decnum::operator+=(const decnum& x)
{
if(x.sign == sign)
return absadd(x);
else if(absge(x))
return abssub(x);
else
{
decnum tmp(*this);
*this = x;
return abssub(tmp);
}
}
decnum& decnum::operator-=(const decnum& x)
{
if(x.sign != sign)
return absadd(x);
else if(absge(x))
return abssub(x);
else
{
decnum tmp(*this);
*this = x;
return abssub(tmp);
}
}
decnum& decnum::operator*=(const decnum& x)
{
if(num == 0) return *this;
if(x.num == 0)
{
num = 0;
return *this;
}
if(sign == x.sign)
sign = 0;
else
sign = 1;
int mul, i, n, newcap, max;
char ch, carry;
char *newval = new char[num + x.num];
newcap = num + x.num;
memset(newval, 0, num + x.num);
decnum a, b;
char *ptr;
for(i=0; i<num && val[i] == 0; i++);
int na = i;
a.val = val + i;
a.num = num - i;
for(i=0; i<num && x.val[i] == 0; i++);
int nb = i;
b.val = x.val + i;
b.num = x.num - i;
ptr = newval + na + nb;
for(n=0; n <= a.num + b.num - 2; n++)
{
mul = 0;
if(n > b.num - 1)
i = n - b.num + 1;
else
i=0;
max = n < a.num-1 ? n : a.num-1;
for(; i<=max; i++)
mul += a.val[i]*b.val[n-i];
carry = 0;
for(i=n; mul > 0 || carry > 0; mul /= 10, i++)
{
ch = ptr[i] + mul % 10 + carry;
if(ch > 9)
{
carry = 1;
ptr[i] = ch - 10;
}
else
{
carry = 0;
ptr[i] = ch;
}
}
}
for(i=a.num + b.num; i>0 && ptr[i-1] == 0; i--);
num = i + na + nb;
if(cap >= num)
{
memcpy(val, newval, num);
delete[] newval;
}
else
{
cap = newcap;
delete[] val;
val = newval;
}
a.val = b.val = NULL;
return *this;
}
decnum& decnum::operator/=(const decnum& x)
{
char ch, carry, fac;
decnum tmp;
int i;
if(x.num == 0) return *this;
if(num < x.num)
{
num = 0;
return *this;
}
if(sign == x.sign)
sign = 0;
else
sign = 1;
char *newval = new char[num - x.num + 1];
memset(newval, 0, num - x.num + 1);
carry = 0;
fac = x.val[x.num-1] + 1;
tmp.val = val + num - x.num + 1;
tmp.cap = tmp.num = x.num -1;
for(i=num-1; i>= x.num-1; i--)
{
tmp.val--;
tmp.num++;
ch = (carry * 10 + val[i]) / fac;
tmp -= x * ch;
while(tmp >= x)
{
tmp -= x;
ch++;
}
newval[i-x.num+1] = ch;
carry = val[i];
}
tmp.val = NULL;
for(i=num-x.num+1; i>0 && newval[i-1] == 0; i--);
num = i;
delete[] val;
val = newval;
return *this;
}
decnum& decnum::operator%=(const decnum& x)
{
char ch, carry, fac;
decnum tmp;
int i;
if(x.num == 0) return *this;
if(num < x.num) return *this;
carry = 0;
fac = x.val[x.num-1] + 1;
tmp.val = val + num - x.num + 1;
tmp.num = x.num - 1;
for(i=num-1; i>= x.num-1; i--)
{
tmp.val--;
tmp.num++;
ch = (carry * 10 + val[i]) / fac;
tmp -= x * ch;
while(tmp >= x)
{
tmp -= x;
ch++;
}
carry = val[i];
}
tmp.val = NULL;
num = tmp.num;
return *this;
}
decnum decnum::operator+(const decnum& x) const
{
decnum tmp = *this;
return tmp += x;
}
decnum decnum::operator-(const decnum& x) const
{
decnum tmp = *this;
return tmp -= x;
}
decnum decnum::operator*(const decnum& x) const
{
decnum tmp = *this;
return tmp *= x;
}
decnum decnum::operator/(const decnum& x) const
{
decnum tmp = *this;
return tmp /= x;
}
decnum decnum::operator%(const decnum& x) const
{
decnum tmp = *this;
return tmp %= x;
}
decnum abs(const decnum& x)
{
decnum tmp(x);
tmp.sign = 0;
return tmp;
}
decnum pow(const decnum& x, int n)
{
decnum tmp(1), fac(x);
for(; n>0; n>>=1)
{
if(n&0x01)
tmp *= fac;
fac *= fac;
}
return tmp;
}
char decnum::root_1(int n)
{
char r = (int)(pow(1+val[num-1], 1.0/n) * pow(10,(num-1.0)/n));
for(; r>0 && pow(decnum(r), n) > *this; r--);
return r;
}
bool decnum::ispow(int n, decnum& r) const
{
if(num == 0)
{
r.num = 0;
return true;
}
if(sign == 1 && (n&1 == 0))
{
r.num = 0;
return false;
}
decnum tmp, p;
r.cap = r.num = (num+n-1) / n;
r.val = new char[r.num];
r.sign = sign;
memset(r.val, 0, r.num);
tmp.val = val + (r.num-1)*n;
tmp.num = num - (r.num-1)*n;
r.val[r.num-1] = tmp.root_1(n);
tmp.val = new char[r.num+1];
tmp.cap = r.num+1;
int v;
p = pow(r, n);
if(p == *this) return true;
for(int i=r.num-2; i>=0; i--)
{
memset(tmp.val, 0, i+1);
tmp.val[i] = 1;
tmp.num = i+1;
tmp += r;
p = (*this - p) / (pow(tmp, n) - p);
if(p.num > 1)
v = 9;
else if(p.num > 0)
v = p.val[0];
else
v = 0;
for(; v>=0; v--)
{
r.val[i] = v;
p = pow(r, n);
if(p == *this)
return true;
if(p < *this)
break;
}
}
return false;
}
bool decnum::ispow() const
{
decnum r, dec2("2", 1);
if(ispow(2, r)) return true;
for(int n=3; r > dec2; n+=2)
{
if(ispow(n, r)) return true;
}
return false;
}
decnum root(const decnum& x, int n)
{
decnum r;
x.ispow(n, r);
return r;
}
decnum div(const decnum& x, const decnum& y, decnum& r)
{
char ch, carry, fac;
decnum d = x, tmp;
int i;
if(y.num == 0) return x;
if(d.num < y.num)
{
r = x;
d = 0;
return d;
}
char *newval = new char[d.num - y.num + 1];
memset(newval, 0, d.num - y.num + 1);
carry = 0;
fac = y.val[y.num-1] + 1;
tmp.val = d.val + d.num - y.num + 1;
tmp.num = y.num - 1;
for(i=d.num-1; i>= y.num-1; i--)
{
tmp.val--;
tmp.num++;
ch = (carry * 10 + d.val[i]) / fac;
tmp -= y * ch;
while(tmp >= y)
{
tmp -= y;
ch++;
}
newval[i-y.num+1] = ch;
carry = d.val[i];
}
r = tmp;
tmp.val = NULL;
for(i=d.num-y.num+1; i>0 && newval[i-1] == 0; i--);
d.num = i;
delete[] d.val;
d.val = newval;
return d;
}
bool operator==(const decnum& x, const decnum&y)
{
if(x.sign != y.sign) return false;
if(x.num != y.num) return false;
for(int i=0; i < x.num; i++)
{
if(x.val[i] != y.val[i])
return false;
}
return true;
}
bool operator!=(const decnum& x, const decnum&y)
{
return !(x==y);
}
bool operator>(const decnum& x, const decnum&y)
{
if(x.sign > y.sign) return false;
if(x.sign < y.sign) return true;
bool retval = (x.sign == 0);
if(x.num > y.num) return retval;
if(x.num < y.num) return !retval;
for(int i=x.num-1; i >= 0; i--)
{
if(x.val[i] > y.val[i])
return retval;
else if(x.val[i] < y.val[i])
return !retval;
}
return false;
}
bool operator<(const decnum& x, const decnum&y)
{
return y > x;
}
bool operator>=(const decnum& x, const decnum&y)
{
if(x.sign > y.sign) return false;
if(x.sign < y.sign) return true;
bool retval = (x.sign == 0);
if(x.num > y.num) return retval;
if(x.num < y.num) return !retval;
for(int i=x.num-1; i >= 0; i--)
{
if(x.val[i] > y.val[i])
return retval;
else if(x.val[i] < y.val[i])
return !retval;
}
return true;
}
bool operator<=(const decnum& x, const decnum&y)
{
return y >= x;
}
ostream& operator<<(ostream&os, const decnum& x)
{
if(x.size() == 0)
os << 0;
else
{
if(x.sign == 1)
os << "-";
for(int i = x.size()-1; i>=0; i--)
os << (int)x.val[i];
}
return os;
}
测试代码:
#include <iostream>
#include <string>
using namespace std;
#include "decnum.h"
int main()
{
decnum x, y, r;
string line;
size_t n = 0;
cout << "input x:" << endl;
getline(cin,line);
x = decnum(line.c_str(), line.length());
cout << "input y:" << endl;
getline(cin,line);
y = decnum(line.c_str(), line.length());
cout << "x = " << x << endl;
cout << "y = " << y << endl;
cout << "x * y =" << x * y << endl;
cout << "x / y =" << x / y << endl;
cout << "x % y =" << x % y << endl;
cout << "div(x, y) =" << div(x , y, r) << endl;
cout << "mod(x, y) =" << r << endl;
cout << "y ^ 2 =" << pow(y, 2) << endl;
cout << "x ^ 1/2 =" << root(x, 2) << endl;
cout << "x is pow = " << x.ispow() << endl;
system("pause");
return 0;
}
来源:https://www.cnblogs.com/phinecos/archive/2008/11/12/1332344.html