高精度--zhengjun
高精度
有些时候题目的数据太大,一般我们常用 \(int\) 的变量就够了,可有时候还不够,要用 \(unsigned\ int\) ,有时候 \(unsigned\ int\) 都不够,就要用 \(long\ long\) ,有时候 \(long\ long\) 还不够,用 \(unsigned\ long\ long\) ,可是还不够,用 \(int\_128\) ,万一还不够呢?
先别跟我谈 \(Python\) ,我知道它自带高精度,我用的是 \(Dev\ c++\)。
于是,高精度就出现了,不过是牺牲了运行速度和空间,换来了精度。
好了,(似乎说了一堆废话)
实现
用一个数组来储存这个数,(可以一个数存4位,我喜欢一个数一位),然后根据竖式加减乘除,然后各种判断,我暂时只是弄了一个正数的高精度。
先看代码吧。
代码
#include<bits/stdc++.h>
#define maxn 100039//最大是10^100040-1
using namespace std;
struct bignum{
int len,s[maxn];//长度,数
//下表小的计数单位小
void clear(){//清零
len=1;
memset(s,0,sizeof(s));
}
bignum operator =(const char *a){//赋值一个字符串
len=strlen(a);
for(int i=1;i<=len;i++)
s[i]=a[len-i]-'0';
return *this;
}
bignum operator =(const int num){//赋值一个数字
char a[maxn];
sprintf(a,"%d",num);//将num转化成一个字符串
*this=a;//因为前面已经定义过了
return *this;
}
bignum operator +(const bignum &a){//加法
bignum c;
c.len=max(len,a.len)+1;//进位
for(int i=1;i<c.len;i++){
c.s[i]+=(s[i]+a.s[i]);
c.s[i+1]+=c.s[i]/10;//处理进位
c.s[i]%=10;
}
if(c.s[c.len]==0)//如果没有进位
c.len--;
return c;
}
bignum operator +=(const bignum &a){
*this=*this+a;//已经定义过了
return *this;
}
bignum operator *(const bignum &a){
bignum c;
c.len=(len+a.len);
for(int i=1;i<=len;i++)//竖式乘法
for(int j=1;j<=a.len;j++){
c.s[i+j-1]+=(s[i]*a.s[j]);
c.s[i+j]+=(c.s[i+j-1]/10);
c.s[i+j-1]%=10;
}
while(c.s[c.len]==0)//处理首位是0
c.len--;
return c;
}
bignum operator *=(const bignum &a){
*this=(*this)*a;//也是定义过了
return *this;
}
bignum operator ^(const int &y){//乘方运算
bignum c=1;
for(int i=1;i<=y;i++)
c*=(*this);//乘法已定义
return c;
}
bool operator <(const bignum &a) const{
if(len!=a.len)
return len<a.len;
for(int i=len;i>=1;i--)//从高位一位一位比较
if(s[i]!=a.s[i])
return s[i]<a.s[i];
return false;
}
bool operator >(const bignum &a) const{
return a<*this;//前面已经定义过
}
bool operator <=(const bignum &a) const{
return !(*this>a);//容斥原理
}
bool operator >=(const bignum &a) const{
return !(*this<a);//容斥原理
}
bool operator ==(const bignum &a) const{
return !((*this<a)||(*this>a));//容斥原理
}
bool operator !=(const bignum &a) const{
return !(*this==a);//容斥原理
}
bool operator <=(const int &a) const{//高精和单精比较
bignum s=a;
return *this<=s;
}
bool operator <(const int &a) const{//高精和单精比较
bignum s=a;
return *this<s;
}
bool operator >=(const int &a) const{//高精和单精比较
bignum s=a;
return *this>=s;
}
bool operator >(const int &a) const{//高精和单精比较
bignum s=a;
return *this>s;
}
bool operator ==(const int &a) const{//高精和单精比较
bignum s=a;
return *this==s;
}
bool operator !=(const int &a) const{//高精和单精比较
bignum s=a;
return *this!=s;
}
void swap(bignum &a,bignum &b){
bignum tmp=a;
a=b;
b=tmp;
}
bignum operator -(const bignum &a) const{
bignum b=*this,c;
if(b<a){
c.len=a.len;
for(int i=1;i<=c.len;i++){
c.s[i]+=(a.s[i]-b.s[i]);
if(c.s[i]<0){
c.s[i]+=10;
c.s[i+1]-=1;
}
}
while(c.len==0)
c.len--;
return c;
}
c.len=b.len;
for(int i=1;i<=c.len;i++){
c.s[i]+=(b.s[i]-a.s[i]);
if(c.s[i]<0){
c.s[i]+=10;
c.s[i+1]-=1;
}
}
while(c.len==0)
c.len--;
return c;
}
bignum operator -=(const bignum &a){
*this=(*this)-a;
return *this;
}
bignum operator /(const int n){
bignum c,b=*this;
c.len=b.len;
int x=0;
for(int i=1;i<=n;i++){
c.s[i]=(x*10+b.s[i])/n;
x=(x*10+b.s[i])%n;
}
while(c.s[c.len]==0)
c.len--;
return c;
}
bignum operator /=(const int a){
*this=*this/a;
return *this;
}
//如果还有一些高精有的而单精没有的运算可以重新定义
//例如:
/*
bignum operator _(const int a){
bignum b=a;//之前定义过
return *this_b;
}
*/
};
ostream& operator <<(ostream &out,const bignum &x){//输出流输出,也是百度学的
for(int i=x.len;i>=1;i--)
printf("%d",x.s[i]);
return out;
}
istream& operator >>(istream &in,const bignum &x){//可以用输入流输入(百度学的)
char a[maxn];
scanf("%s",&a);//直接读入字符串
int len=strlen(a);
x.len=len;
for(int i=1;i<=len;i++)
x.s[i]=a[len-i]-'0';//注意要减掉‘0’
return in;
}
int main(){
return 0;
}
最后提醒一点, \(operator\) 的参数最多只能有 \(1\) 个
如果超过 \(1\) 个,要么在结构体外面写,要么写成一个函数