LongInt Algorithm::Karatsuba(LongInt a_1, LongInt b_1)
{
    if(a_1.length()==1 || b_1.length()==1)//&&
    {
        return a_1*b_1;
    }

    int length;
    if(a_1.length()!=1 && b_1.length()!=1)
    {
        length=(a_1.length() >= b_1.length() ? b_1.length() : a_1.length() )/2;
        LongInt a_2;
        a_2.number=a_1.getVector_of_Number(a_1.length()-length);
        LongInt b_2;
        b_2.number=b_1.getVector_of_Number(b_1.length()-length);
        LongInt ab_1,ab_2;
        ab_1=Karatsuba(a_1,b_1);
        ab_2=Karatsuba(a_2,b_2);
        return ( (((Karatsuba(a_1+a_2,b_1+b_2)-ab_1-ab_2)<<length)
                  + ab_2)
                 + (ab_1<<(2*length))
               );
    }
}
LongInt Algorithm::Strassen (LongInt a, LongInt b)
{
    int n=1;
    while(n<a.length())
    {
        n<<=1;
    }
    n<<=1;
    QVector< std::complex<double> > fa,fb,res(n);
    while(!a.isEmpty())
    {
        fa.push_front(a.number.takeFirst());
    }
    while(!b.isEmpty())
    {
        fb.push_front(b.number.takeFirst());
    }
    while(fa.length()<n)
    {
        fa.push_back(0);
    }
    while(fb.length()<n)
    {
        fb.push_back(0);
    }
    FFT(fa,0);
    FFT(fb,0);
    for(int i=0;i<fa.length();i++)
    {
        fa[i]*=fb[i];
    }
    FFT(fa,1);
    while(!fa.isEmpty())
    {
        a.push_front(fa.takeFirst().real()+0.5);
    }
    a.normalization();

    return a;
}
LongInt Algorithm::Toom_Cook(LongInt a, LongInt b)
{
    /*/
    a=LongInt("529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450");
    b=LongInt("29834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450529834750827340585463450");
    qDebug()<<a.length();
    LongInt z=Strassen(a,b);
    /*/
    //===T1===========initialization=table=and=stack===
    qDebug()<<"Hello Lord of Iteration";
    QStack<LongInt> U,V;
    QStack<LongInt> W;
    QStack<int> C;

    int Index,i,j;//for iteration;
    //=======================Table===========
    int k=1;
    int Q=2,R=1;
    Table table={4,2};

    QVector<Table> qv_table;
    qv_table<<table<<table;
    QVector<Table>::iterator iter_table;//=qv_table.begin();

    int last_q=4;

    qDebug()<<qA<<"\"(0)\""<<Q<<R<<table.q<<table.r;
    while(a.length()>(qv_table.last().q+last_q))
    {
        qDebug()<<"algorithm.cpp:"<<"("+QString::number(k)+")"<<Q<<R<<table.q<<table.r;
        k++;
        Q+=R;
        table.q*=table.r;
        R++;
        if(R*R<=Q)//if((R+1)^2>=Q) R++;
        {
            table.r*=2;
        }
        else R--;
        last_q=qv_table.last().q;
        qv_table<<table;
    }
    qDebug()<<"algorithm.cpp:"<<"("+QString::number(k)+")"<<Q<<R<<table.q<<table.r;
    iter_table=qv_table.end();
    iter_table--;
    LongInt numbers[10*iter_table->r+1];
    //===================T2============================
    C.push(-1);
    C<<a.number<<-5<<b.number;
    a.clear();
    b.clear();
    int forSwitch=1;//iter_table--;
    //====================Cycle========================
    //bool isEnd=0;
    while(1)
    {
        switch(forSwitch)
        {
        case 1://T3
        {
            k--;
            iter_table--;
            //qDebug()<<"K="<<k;
            if(!k)
            {
                a.clear();
                b.clear();
                //qDebug()<<"C="<<C;
                while(!C.isEmpty())
                {
                    Q=C.pop();
                    if(Q>=0)
                    {
                        b.push_front(Q);
                    }
                    else
                    {
                        break;
                    }
                }
                //qDebug()<<"C="<<C;
                while(!C.isEmpty())
                {
                    Q=C.pop();
                    if(Q>=0)
                    {
                        a.push_front(Q);
                    }
                    else
                    {
                        C.push(Q);
                        break;
                    }
                }
                //qDebug()<<"algorithm.cpp:"<<a<<"*"<<b<<"=";
                forSwitch=5;
                a*=b;
                //qDebug()<<"algorithm.cpp:"<<a;
            }
            else
            {
                forSwitch=2;
            }
            break;
        }
        case 2://T4 T5
        {
            //=====T4=========
            Index=0;
            numbers[0].clear();
            //qDebug()<<"T4 C"<<C;

            while(!C.isEmpty())
            {
                Q=C.pop();
                if(Q>=0)
                {
                    if(numbers[Index].length()>=iter_table->q)
                    {
                        //qDebug()<<"algorithm.cpp:("<<Index<<")"<<numbers[Index];
                        numbers[Index].normalization();
                        Index++;
                        numbers[Index].clear();
                    }
                    numbers[Index].push_front(Q);
                }
                else
                {
                    break;
                }
            }
            //qDebug()<<"algorithm.cpp:("<<Index<<")"<<numbers[Index];
            R=iter_table->r+Index;
            //qDebug()<<R;
            //qDebug()<<Index;
            for(j=0;j<=R;j++)
            {
                a=numbers[Index];
                for(i=Index-1;i>=0;i--)
                {
                    a*=j;
                    a+=numbers[i];
                }
                U<<a;
            }
            Index=0;
            numbers[0].clear();
            while(!C.isEmpty())
            {
                Q=C.pop();
                if(Q>=0)
                {
                    if(numbers[Index].length()>=iter_table->q)
                    {
                        //qDebug()<<"algorithm.cpp:("<<Index<<")"<<numbers[Index];
                        numbers[Index].normalization();
                        Index++;
                        numbers[Index].clear();
                    }
                    numbers[Index].push_front(Q);
                }
                else
                {
                    C.push(Q);
                    break;
                }
            }
            //qDebug()<<"algorithm.cpp:("<<Index<<")"<<numbers[Index];
            //qDebug()<<Index;
            for(j=0;j<=R;j++)
            {
                a=numbers[Index];
                //qDebug()<<"algorithm.cpp:j="<<j;
                for(i=Index-1;i>=0;i--)
                {
                    a*=j;
                    a+=numbers[i];
                }
                //qDebug()<<"algorithm.cpp:a="<<a;
                V<<a;
            }
            //qDebug()<<"algorithm.cpp:V="<<V;
            //=====T5=========
            if(!U.isEmpty()||!V.isEmpty())
            {
                C<<-2<<V.pop().number<<-5<<U.pop().number;
                while(!U.isEmpty()||!V.isEmpty())
                {
                    C<<-3<<V.pop().number<<-5<<U.pop().number;
                }
            }
            else
            {
                //qDebug()<<"Error algorithm.cpp: U or V Empty";
            }
            //qDebug()<<"C="<<C;
            b.clear();
            b.push_front(-4);
            W<<b;
            forSwitch=1;
            break;
        }
        case 3://T6
        {
            W<<a;
            forSwitch=1;
            //qDebug()<<"algorithm.cpp:a="<<a;
            break;
        }
        case 4://T7 T8 T9
        {
            //qDebug()<<W<<"\n";
            //W.clear();
            //W<<-4<<10<<304<<1980<<7084<<18526;
            Index=-1;
            while (!W.isEmpty())
            {
                //b=W.pop();
                Index++;
                //qDebug()<<"W="<<W;
                numbers[Index]=W.pop();
                //qDebug()<<W.length();
                if(numbers[Index]<0)
                {
                    //qDebug()<<W.length();
                    Index--;
                    break;
                }
            }
            //qDebug()<<W;
            //=====T7=========
            for(j=1;j<=Index;j++)
            {
                for(i=0;i<=Index-j;i++)
                {
                    numbers[i]=(numbers[i]-numbers[i+1])/LongInt(j);
                    //qDebug()<<"numb"<<numbers[i]<<j;
                }
                //qDebug()<<numbers[Index-j+1]<<j;
            }
            //qDebug()<<numbers[Index-j+1];

            /*/
            for(i=0;i<=Index;i++)
            {
                qDebug()<<"(T7)numbers="<<numbers[i];
            }
            /*/

            //=====T8=========
            //qDebug()<<"";
            for(j=Index-1;j>=1;j--)
            {
                for(i=Index-j;i>=1;i--)
                {
                    //qDebug()<<j<<i;
                    numbers[i]-=numbers[i-1]*j;
                }
            }

            /*/
            for(i=0;i<=Index;i++)
            {
                qDebug()<<"(T8)numbers="<<numbers[i];
            }
            /*/

            //=====T9=========
            a=numbers[0];
            //qDebug()<<iter_table->q;
            for(i=1;i<=Index;i++)
            {
                a=(a<<iter_table->q)+numbers[i];
                //qDebug()<<a<<a.length()<<iter_table->q<<numbers[i];
            }
            //qDebug()<<"";
            forSwitch=5;
            break;
        }
        case 5://T10
        {
            k++;
            iter_table++;
            if(!C.isEmpty())
            switch(C.pop())
            {
            case -1:
            {
                /*/
                qDebug()<<"a=  "<<a;
                qDebug()<<"z=  "<<z;
                if(a==z)
                {
                    qDebug()<<"a=z";
                }
                /*/
                return a;
                break;
            }
            case -2:
            {
                W<<a;
                forSwitch=4;
                //qDebug()<<"-2";
                break;
            }
            case -3:
            {
                forSwitch=3;
                //qDebug()<<"-3";
                break;
            }
            default:
            {
                //qDebug()<<"error";
                break;
            }
            }
            else
            {
                //qDebug()<<"Error algorithm.cpp: C Empty";
            }

            break;
        }
        }
    }
}