怎样用两个32位数,来实现64位的乘除运算?

时间:2021-10-03 14:43:49
题目:只能用int 或 usigned int 型数据, 不能用浮点数,
      请计算实现整数运算 a*b/c, (a,b,c都是非常大的32位整数)
思路:用32位来模拟64位的加减乘除,可能是一个能够保证计算精度的好方法。
      请老师指点,如何实现?

9 个解决方案

#1


能内嵌汇编不能?

#2


想办法手工处理一个进位和借位就是了。

#3


考虑用数组 看行不

#4


直接在网上找大数运算之类的类 吧。

#5


大数运算,支持任意长度的 + - * / %
http://blog.csdn.net/akirya/archive/2008/02/04/2083998.aspx

#6


我看到了一段代码挺好的,能实现 a*b/c的功能,
乘法做的是对的,但是除法做的好像不对,
那位老师帮着修正一下


//   计算(u*v)%m

unsigned   mul_mod(unsigned   u,   unsigned   v,   unsigned   z)
{
        //   如果u*v没有溢出,   则直接计算

        if((u*v)/u   ==   v)   return   (u*v)%z;

        //   进行长乘法(结果为64位)

        unsigned   u0,   v0,   w0;
        unsigned   u1,   v1,   w1,   w2,   t;
 
        u0   =   u   &   0xFFFF;     u1   =   u   > >   16;
        v0   =   v   &   0xFFFF;     v1   =   v   > >   16;
        w0   =   u0*v0;
        t     =   u1*v0   +   (w0   > >   16);
        w1   =   t   &   0xFFFF;
        w2   =   t   > >   16;
        w1   =   u0*v1   +   w1;

        //   x为高32位,   y为低32位

        unsigned   x   =   u1*v1   +   w2   +   (w1   > >   16);
        unsigned   y   =   u*v;

        //   进行长除法(被除数为64位)
 
        for   (int   i   =   1;   i   <=   32;   i++)
        {
                t   =   (int)x   > >   31;                       //   All   1 's   if   x(31)   =   1.  

                x   =   (x   < <   1)   |   (y   > >   31);       //   Shift   x   ||   y   left  
                y   < <=   1;                                         //   one   bit.
               
                if((x|t)   > =   z)   {   x   -=   z;   y++;   }  
        }

        return   x;         //   y为商,   x为余数
}

#7


重传一下

//   进行长除法(被除数为64位)
 
        for   (int   i   =   1;   i   <=   32;   i++)
        {
                t   =   (int)x   > >   31;                       //   All   1 's   if   x(31)   =   1.  

                x   =   (x   < <   1)   |   (y   > >   31);       //   Shift   x   ||   y   left  
                y   < <=   1;                                         //   one   bit.
               
                if((x|t)   > =   z)   {   x   -=   z;   y++;   }  
        }

        return   x;         //   y为商,   x为余数 

#8


               
                if((x  |  t)   > =   z)   {   x   -=   z;   y++;   }  
        

#9


好像没那么简单,呵呵.

#1


能内嵌汇编不能?

#2


想办法手工处理一个进位和借位就是了。

#3


考虑用数组 看行不

#4


直接在网上找大数运算之类的类 吧。

#5


大数运算,支持任意长度的 + - * / %
http://blog.csdn.net/akirya/archive/2008/02/04/2083998.aspx

#6


我看到了一段代码挺好的,能实现 a*b/c的功能,
乘法做的是对的,但是除法做的好像不对,
那位老师帮着修正一下


//   计算(u*v)%m

unsigned   mul_mod(unsigned   u,   unsigned   v,   unsigned   z)
{
        //   如果u*v没有溢出,   则直接计算

        if((u*v)/u   ==   v)   return   (u*v)%z;

        //   进行长乘法(结果为64位)

        unsigned   u0,   v0,   w0;
        unsigned   u1,   v1,   w1,   w2,   t;
 
        u0   =   u   &   0xFFFF;     u1   =   u   > >   16;
        v0   =   v   &   0xFFFF;     v1   =   v   > >   16;
        w0   =   u0*v0;
        t     =   u1*v0   +   (w0   > >   16);
        w1   =   t   &   0xFFFF;
        w2   =   t   > >   16;
        w1   =   u0*v1   +   w1;

        //   x为高32位,   y为低32位

        unsigned   x   =   u1*v1   +   w2   +   (w1   > >   16);
        unsigned   y   =   u*v;

        //   进行长除法(被除数为64位)
 
        for   (int   i   =   1;   i   <=   32;   i++)
        {
                t   =   (int)x   > >   31;                       //   All   1 's   if   x(31)   =   1.  

                x   =   (x   < <   1)   |   (y   > >   31);       //   Shift   x   ||   y   left  
                y   < <=   1;                                         //   one   bit.
               
                if((x|t)   > =   z)   {   x   -=   z;   y++;   }  
        }

        return   x;         //   y为商,   x为余数
}

#7


重传一下

//   进行长除法(被除数为64位)
 
        for   (int   i   =   1;   i   <=   32;   i++)
        {
                t   =   (int)x   > >   31;                       //   All   1 's   if   x(31)   =   1.  

                x   =   (x   < <   1)   |   (y   > >   31);       //   Shift   x   ||   y   left  
                y   < <=   1;                                         //   one   bit.
               
                if((x|t)   > =   z)   {   x   -=   z;   y++;   }  
        }

        return   x;         //   y为商,   x为余数 

#8


               
                if((x  |  t)   > =   z)   {   x   -=   z;   y++;   }  
        

#9


好像没那么简单,呵呵.