#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
;
}