zoukankan      html  css  js  c++  java
  • C++ 高精度小数

    当前我在咕啥

    1.目前咕压位高精。

    2.想都还没想的k次方根

    3.除法还没优化

    4.快速乘

    5为啥n^2的乘法比nlogn的快,算了之后用分治乘来折腾下吧算了之后用FFT优化一下吧

    1.1.2 版本内容

    1.优化了加法乘法减法

    2.增加了k次方根

    3.优化掉了1.1.1版本

    1.1版本的功能

    1.新增开方功能(目前只能开平方根,精度不理想,后面用牛顿迭代法试试吧)

    2.新增快速幂(目前没遇到bug,过了模板)

    3.有两种输出方式(fprint为小数形式,mprint输出方式见P1517)

    4.快读

    1.0版本的功能

    1.加减乘除

    2.double与该类型加减乘除(加减还没弄)

    3.比较大小(小于等于大于)

    4.自定义数组长度($width$),小数点位数($bas$),除法精度($eps$),double转该类型精度($deps$)

    5.都测了一下,应该没有问题

    目前已知的缺陷、

    1.不能与其他类型多次同时读入(应该能和string同时读入),
    比如你前一半读入该类型后一半其他类型是可以的,但是你再读一次该类型就要炸
    接了个快读上去,解决了

    2.代码丑

    4.没有第三点

    5.double转小数精度不高,貌似在1e-6左右

    6.string转小数好像没测

    7.后面应该可以优化前面的代码,但是还在加功能,所以没优化。

    8.使用dev c++ 现在用上了vscode

    有神仙说有bug,目前乘法法肯定不会有bug(能过一整道题),所以问题可能出现在减法和加法上,除法大概率不会bug, 修复了

    之前0.02会玄学变成0.2 修复了

    change_num锅了 好了

    暂且命名为mdob

    转载标明出处

    有Bug请指出

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<set>
    #include<map>
    #include<algorithm>
    
    using namespace std;
    
    // code mmm uid:38636 
    //rules
    // 1  a double which is <1 consider as 0.xxx
    // 2  a double base place is a const(now here is 69),and the point  
    // 3  ab integer consider as x.0
    
    //#define int long long
    
    const int width=1020;
    const int bas=500;
    const int eps=25;
    const int deps=1; //double eps 
    
    struct mdob{
    
        int a[width];
        int l,r;
        int fg,wfg;
    
        mdob()
        {
            memset(a,0,sizeof(a));
            l=r=bas;
            fg=0;
            wfg=0;
        }
    
        inline void mov(int p)
        {
            if(p==0) return ;
            if(p>0) for(int i=l;i<=r;i++) 
            {
                if(i-p<=bas&&i>bas) a[i-p-1]=a[i],a[i]=0; else if(i!=bas) a[i-p]=a[i],a[i]=0;
            }
            if(p<0) for(int i=r;i>=l;i--) 
            {
                if(i-p>=bas&&i<bas) a[i-p+1]=a[i],a[i]=0; 
                else if(i!=bas) a[i-p]=a[i],a[i]=0;
            }
            if(p>0) 
            {
                l=l-p; if(a[l]==0) l++;
                r=max(r-p,bas+1);
            }
            if(p<0) 
            {
                l=min(l-p,bas-1);
                r=max(r-p,bas+1); if(a[r]==0) r--;
            }
    
            return ;
        }
    
        void war()
        {
            if(fg==0) return;
            wfg=1;
            for(int i=l;i<=r;i++)
            {
                if(i==bas) continue;
                a[i]=-a[i];
            }
        }
    
        void peace()
        {
            if(fg==0) return;
            wfg=0;
            for(int i=l;i<=r;i++)
            {
                if(i==bas) continue;
                a[i]=-a[i];
            }
        }
    
    //judge a num which <0 look at the firstplace 
    
        inline void check()
        {
            int i,leave=0;
            if(l==bas) l--;
            if(r==bas) r--;
            if(wfg) peace();
            for(i=r;i>=l;i--) 
            {
                if(i==bas) continue;
                a[i]+=leave;
                leave=0;
                if(a[i]>=10) 
                {
                    leave+=a[i]/10,a[i]%=10;
                    if(i==l) l--;
                }
            }       
            while(a[l]==0&&l<bas-1) l++; //consider as 0,xxx
            while(a[r]==0&&r>bas+1) r--; //consider as xxx.0
        }
    
        inline void clr()
        {
            //memset(a,0,sizeof(a));
            for(int i=l;i<=r;i++) a[i]=0;
            l=r=bas;
            fg=0;
        }
    
        inline void mread()
        {
            clr();
            l=r=bas;
            fg=0;
            stack <int> s;
            queue <int> q;
            char p;
            p=getchar();
            while(p<'0'||p>'9') if(p=='-') fg=1,p=getchar();
            while(p>='0'&&p<='9') s.push(p-'0'),p=getchar();
            while(!s.empty()) a[--l]=s.top(),s.pop();
            if(p!='.') 
            {
                a[++r]=0;
                return ;
            }
            p=getchar();
            while(p>='0'&&p<='9') q.push(p-'0'),p=getchar();
            while(!q.empty()) a[++r]=q.front(),q.pop();
            return ;
            check();
        }
    
        int _10n(int x)
        {
            if(x==0) return 1;
            if(x==1) return 10;
            if(x==2) return 100;
            if(x==3) return 1000;
            if(x==4) return 10000;
            if(x==5) return 100000;
            if(x==6) return 1000000;
            if(x==7) return 10000000;
            return 0; // vscode 的要求
        }
    
        void doudob(double x)
        {
            clr();
            double mutis;
            if(0-x>0.0000001) fg=1,x=-x; 
            mutis=x-floor(x);
            int rp,lp; //point right,point left
            lp=floor(x); 
            mutis=1.0*mutis*_10n(deps);
            l=r=bas;
            queue <int> s;
            stack <int> q;
            while(lp) 
            s.push(lp%10),lp/=10;
            int ts=1;
            rp=floor(mutis);
            while(ts<=deps)
            {
                if(rp)
                q.push(rp%10),rp/=10;
                else q.push(0);
                ts++;
            }
            while(!s.empty()) a[--l]=s.front(),s.pop();
            while(!q.empty()) a[++r]=q.top(),q.pop();
            l=min(l,bas-1);
            r=max(r,bas+1);
        }
    
        inline void strdob(string st)
        {
            int muti=st.size();
            clr();
            l=r=bas;
            fg=0;
            stack <int> s;
            queue <int> q;
            int p=0;
            while((st[p]<'0'||st[p]>'9')&&p<muti) if(st[p]=='-') fg=1,p++;
            while(st[p]>='0'&&st[p]<='9'&&p<muti) s.push(st[p]-'0'),p++;
            while(!s.empty()) a[--l]=s.top(),s.pop();
            if(st[p]!='.') 
            {
                a[++r]=0;
                return ;
            }
            p++;
            while(st[p]>='0'&&st[p]<='9'&&p<muti) q.push(st[p]-'0'),p++;
            while(!q.empty()) a[++r]=q.front(),q.pop();
            return ;
            check();
        }
    
        inline int getnowplace(int p)
        {
            if(p>bas) return p-l;
            else return p-l+1;
        }
    
        inline void mprint()  //printf like  P1517 luogu
        {
            check();
            int i;
            if(fg) cout<<'-';
            if(a[l]!=0)for(i=l;i<bas;i++) cout<<a[i];
            if(r==bas) 
            {
                cout<<endl;
                return ;
            }
            cout<<".";
    		for(i=bas+1;i<=r;i++) cout<<a[i];
    		cout<<endl;
            cout<<endl;
            return ;
        }
    
        inline void fmprint()  //printf like  P1517 luogu
        {
            check();
            int i;
            if(fg) cout<<'-';
            if(a[l]!=0)for(i=l;i<bas;i++) cout<<a[i];
            cout<<".";
            for(i=bas+1;i<=r;i++) cout<<a[i];
            cout<<endl;
            return ;
        }
    
        inline void change_num(int x)
        {
            clr();
            if(x<0) fg=1,x=-x;
            while(x)
            {
                a[--l]=x%10;
                x/=10;
            }
            a[++r]=0;
            check();
        }
    
        inline int findl()
        {
            int i=l;
            while(a[i]<=0) if(i==bas-1) i+=2; else i++;
            return i;
        }
    
    }; 
    
    //n^2的乘法
    
    mdob getmul(mdob x,mdob y)
    {
        int target[width];
        //memset(target,0,sizeof(target));
        mdob ans;
        ans.l=ans.r=bas;
        ans.clr();
        ans.fg=x.fg^y.fg;
        int i,j;
        int zeropla=x.getnowplace(bas-1)+y.getnowplace(bas-1);
        int trg; //结束位置
        trg=x.getnowplace(x.r)+y.getnowplace(y.r)-1;
        for(i=1;i<=trg;i++) target[i]=0;
        for(i=x.l;i<=x.r;i++)
        {
            if(i==bas) continue;
            for(j=y.l;j<=y.r;j++)
            {
                if(j==bas) continue;
                target[x.getnowplace(i)+y.getnowplace(j)-1]+=x.a[i]*y.a[j];
            }
        }
        int muti=x.getnowplace(x.r)+y.getnowplace(y.r)-1;
        for(i=zeropla-1;i>=1;i--) ans.a[--ans.l]=target[i];
        for(i=zeropla;i<=muti;i++) ans.a[++ans.r]=target[i];
        ans.check();
        return ans;
    }
    
    mdob getmul(mdob x,int y)
    {
        mdob k;
        k.change_num(y);
        return getmul(x,k);
    }
    
    mdob operator -(mdob x,mdob y)
    {
        mdob ans;
        int looker=0;
        y.fg=1-y.fg;
        y.war();
        x.war();
        int i,st=min(x.l,y.l),ed=max(x.r,y.r);
        for(i=st;i<=ed;i++) 
        {
            if(i==bas) continue;
            ans.a[i]=x.a[i]+y.a[i];
            if(ans.a[i]!=0&&!looker) looker=1,ans.fg=ans.a[i]<0;
        }
        ans.l=st;
        ans.r=ed;
        int muti=x.getnowplace(x.r)+y.getnowplace(y.r)-1;
        if(ans.fg==1)
        {
            for(i=ed;i>=st+1;i--) if(ans.a[i]>0) 
            {
                ans.a[i]-=10;
                if(i-1==bas) ans.a[i-2]++; else ans.a[i-1]++;   
            }
        }
        if(ans.fg==0)
        {
            for(i=ed;i>=st+1;i--) if(ans.a[i]<0) 
            {
                ans.a[i]+=10;
                if(i-1==bas) ans.a[i-2]--; else ans.a[i-1]--;   
            }
        }
        ans.peace();
        ans.check();
        return ans;
    }
    
    mdob operator +(mdob x,mdob y)
    {
        mdob ans;
        int looker=0;
        y.war();
        x.war();
        int i,st=min(x.l,y.l),ed=max(x.r,y.r);
        for(i=st;i<=ed;i++) 
        {
            if(i==bas) continue;
            ans.a[i]=x.a[i]+y.a[i];
            if(ans.a[i]!=0&&!looker) looker=1,ans.fg=ans.a[i]<0;
        }
        ans.l=st;
        ans.r=ed;
        int muti=x.getnowplace(x.r)+y.getnowplace(y.r)-1;
        if(ans.fg==1)
        {
            for(i=ed;i>=st+1;i--) if(ans.a[i]>0) 
            {
                ans.a[i]-=10;
                if(i-1==bas) ans.a[i-2]++; else ans.a[i-1]++;   
            }
        }
        if(ans.fg==0)
        {
            for(i=ed;i>=st+1;i--) if(ans.a[i]<0) 
            {
                ans.a[i]+=10;
                if(i-1==bas) ans.a[i-2]--; else ans.a[i-1]--;   
            }
        }
        ans.peace();
        ans.check();
        return ans;
    }
    
    //10*log(n)的除法
    
    mdob operator /(mdob x,mdob y)
    {
        mdob ans;
        ans.l=ans.r=bas;
        ans.clr();
        ans.fg=x.fg^y.fg;
        int i,j;
        int deltapla;
        int xl,yl;
        i=x.l; while(x.a[i]<0) if(i==bas-1) i+=2; else i++; xl=i;
        i=y.l; while(y.a[i]<0) if(i==bas-1) i+=2; else i++; yl=i;
        deltapla=yl-xl;
        if((xl<bas&&yl>bas)||(xl>bas&&yl<bas)) 
        {
            if(deltapla>0) deltapla--; else deltapla++; 
        }
        y.mov(deltapla);
        mdob looker;
        int p=y.l;
        x.fg=0;
        y.fg=0;
        ans.l=p;
        ans.r=bas+eps;
        while(p<=bas+eps)
        {
            if(p==bas) p++;
            int con=0;
            while(!x.fg)
            {
                x=x-y;
                con++;
            }
            con--;
            if(con==-1) con++;
            else
            {
                x=x+y;  
                ans.a[p]+=con;
            }
            y.mov(-1);
            p++;
        }
        ans.check();
        return ans;
    }
    
    //o(n log n )乘法
    
    mdob operator *(mdob a,mdob b)
    {
        mdob ans;
        mdob looker;
        ans.clr();
        int fg=a.fg^b.fg;
        a.fg=b.fg=0;
        int i,j;
        for(i=b.l;i<=bas;i++)
        {
            looker.clr();
            if(b.a[i]==0) continue;
            looker=getmul(a,b.a[i]);
            looker.mov(bas-i-1);
            ans=ans+looker;
        }
        for(i=bas+1;i<=b.r;i++)
        {
            looker.clr();
            if(b.a[i]==0) continue;
            looker=getmul(a,b.a[i]);
            looker.mov(bas-i);
            ans=ans+looker;
        }
        ans.fg=fg;
        return ans;
    }
    
    
    bool operator ==(mdob a,mdob b)
    {
        int al=a.findl();
        int bl=a.findl();
        int looker=0;
        if(a.fg==1) looker=1;
        if(al<bl&&looker) return 0;
        if(al>bl&&!looker) return 0;
        if(al>bl&&looker) return 0;
        if(al<bl&&!looker) return 0; 
        int i;
        int st=a.l;
        int ed=max(a.r,b.r);
        for(i=st;i<=ed;i++)
        {
            if(i==bas) continue;
            if(a.a[i]!=b.a[i]) return 0;
        }
        return 1;
    }
    
    bool operator <(mdob a,mdob b)
    {
        if(a==b) return 0;
        if(a.fg>b.fg) return 1;
        if(a.fg<b.fg) return 0;
        int al=a.findl();
        int bl=b.findl();
        int looker=0;
        if(a.fg==1) looker=1;
        if(al<bl&&looker) return 1;
        if(al>bl&&!looker) return 1;
        if(al>bl&&looker) return 0;
        if(al<bl&&!looker) return 0; 
        int i;
        int st=a.l;
        int ed=max(a.r,b.r);
        for(i=st;i<=ed;i++)
        {
            if(i==bas) continue;
            if(a.a[i]>b.a[i]&&looker) return 1;
            if(a.a[i]>b.a[i]&&!looker) return 0;
            if(a.a[i]<b.a[i]&&looker) return 0;
            if(a.a[i]<b.a[i]&&!looker) return 1;
        }
        return 0; //vscode的要求
    }
    
    bool operator >(mdob a,mdob b)
    {
        int x=0,y=0;
        x=a==b;
        y=a<b;
        if(x==1) return 0;
        return y^1;
    }
    
    bool operator <=(mdob a,mdob b)
    {
        return (a<b||a==b);
    }
    
    bool operator >=(mdob a,mdob b)
    {
        return (a>b||a==b);
    }
    
    mdob operator *(mdob x,double y)
    {
        mdob ans,yy;
        yy.doudob(y);
        ans=x*y;
        return ans;
    }
    
    mdob operator +(mdob x,int y)
    {
        mdob yy;
        yy.change_num(y);
        return x+yy;
    }
    
    mdob operator -(mdob x,int y)
    {
        mdob yy;
        yy.change_num(y);
        return x-yy;
    }
    
    mdob operator /(mdob x,double y)
    {
        mdob ans,yy;
        yy.doudob(y);
        ans=x/yy;
        return ans;
    }
    
    mdob operator /(mdob x,int y)
    {
        double c=1.0*y;
        mdob ans;
        ans=x/c;
        return ans;
    }
    
    mdob _sqrt(mdob x)
    {
        mdob l,r,mid;
        l.strdob("0.0");
        mdob target,ans;
        target.strdob("1.0");
        target.mov(-deps); 
        //just for which is >0 
        if(x.fg==1) return l;
        if(x==l) return l;
        r=x;
        x.mprint();
        while(r-l>target)
        {
            mid=(l+r)/2;
            mid.r=min(mid.r,deps+bas+1);
            if(mid*mid<=x) l=mid,ans=mid;
            else r=mid;
        }
        if(mid.a[mid.r]>=5) mid.a[--mid.r]++;
        return ans;
     }
    
    mdob _pow(int x,mdob &y)
    {
        mdob ans;
        if(x==0) {ans.strdob("1.0"); return ans;}
        if(x==1) return y;
        ans.strdob("1.0");
        if(x&1) ans=ans*y;
        ans=ans*_pow(x/2,y)*_pow(x/2,y); 
        return ans;
    }
    
    mdob take_root(int x,mdob y)
    {
        mdob target;
        target.strdob("1.0");
        target.mov(-deps); 
        mdob ans;
        ans.change_num(0);
        if(x<=0) return ans;
        if(y.fg==1&&(x&1)==0) return ans;
        if(y==ans) return ans;
        int looker=0;
        if(y.fg) looker=1,y.fg=0;
        mdob l,r,mid;
        l=ans; r=y;
        while(r-l>target)
        {
            mid=(l+r)/2;
            mid.r=min(mid.r,deps+bas+1);
            if(_pow(x,mid)<=y) l=mid,ans=mid;
            else r=mid;
        }
        if(ans.a[bas+1]>=5&&!looker) ans=ans+1;
        else if(ans.a[bas+1]<=5&&looker) ans=ans-1;
        if(looker) ans.fg=1;
        return ans;
    }
    
    int qread()
    {
        int ans=0,f=1;
        char c=getchar();
        while(!isdigit(c)) {if(c=='-') f=-1; c=getchar(); };
        while(isdigit(c)) { ans=ans*10+c-'0'; c=getchar(); }
        return f*ans;
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        int i,j;
        mdob a,b,c;
        double t,t2;
        int x;
        string s; 
        while(1)
        {
            a.mread();
            b.mread();
            c=a*b;
            c.mprint();
        }
        return 0;
    }
    
  • 相关阅读:
    创建部署规划
    并发容器Map之一:(jdk1.8) ConcurrentHashMap的红黑树实现分析
    CopyOnWrite容器之二:CopyOnWriteArraySet
    jQuery1.5的新特征subclass——jQuery插件机制的救赎
    getElementsByTagName
    facebook是如何管理代码的
    由addClass衍生出来的字符串去重问题
    节点排序
    Sizzle是怎样工作的
    我的模块加载系统 v3
  • 原文地址:https://www.cnblogs.com/zsx6/p/13526348.html
Copyright © 2011-2022 走看看