两个64位整数相乘 取高64位的值



#define CL_LONG_MIN  ((long long) -0x7FFFFFFFFFFFFFFFLL - 1LL)
#define CL_LONG_MAX  ((long long) 0x7FFFFFFFFFFFFFFFLL)
#define CL_ULONG_MAX ((ulong) 0xFFFFFFFFFFFFFFFFULL)


void multiply_unsigned_64_by_64( ulong sourceA, ulong sourceB, ulong *destLow, ulong *destHi )
{
ulong lowA, lowB;
ulong highA, highB;

// Split up the values
lowA = sourceA & 0xffffffff;
highA = sourceA >> 32;
lowB = sourceB & 0xffffffff;
highB = sourceB >> 32;

ulong aHibHi = highA * highB;
ulong aHibLo = highA * lowB;
ulong aLobHi = lowA * highB;
ulong aLobLo = lowA * lowB;
 
 
    ulong aLobLoHi = aLobLo >> 32;
    ulong aLobHiLo = aLobHi & 0xFFFFFFFFULL;
    aHibLo += aLobLoHi + aLobHiLo;
    
    *destHi = aHibHi + (aHibLo >> 32 ) + (aLobHi >> 32);             // Cant overflow
    *destLow = (aHibLo << 32) | ( aLobLo & 0xFFFFFFFFULL );
}


void multiply_signed_64_by_64( long long sourceA, long long sourceB, long long *destLow, long long *destHi )
{
    // Find sign of result
    long long aSign = sourceA >> 63;
    long long bSign = sourceB >> 63;
    long long resultSign = aSign ^ bSign;


    // take absolute values of the argument
    sourceA = (sourceA ^ aSign) - aSign;
    sourceB = (sourceB ^ bSign) - bSign;


    ulong hi;
    multiply_unsigned_64_by_64( (ulong) sourceA, (ulong) sourceB, destLow, &hi );


    // Fix the sign
    if( resultSign )
    {
        *destLow ^= resultSign;
        hi  ^= resultSign;
        *destLow -= resultSign;
        
        //carry if necessary
        if( 0 == *destLow )
            hi -= resultSign;
    }
    
    *destHi = (long long) hi;

}



#define lb(x) (x) & 0xffffffff
#define hb(x) ((x) >> 32)&0xffffffff 


unsigned long long __OVERLOADABLE__ mul_hi( unsigned long long x, unsigned long long y)
{
unsigned long long xh = hb(x);
unsigned long long xl = lb(x);
 
unsigned long long yh = hb(y);
unsigned long long yl = lb(y);
 
unsigned long t = lb( xh*yl + xl*yh );
return  (xh*yh + (( xh*yl + xl*yh)>>32) + ( pow(2, 64)-1 -t*pow(2,32) < xl*yl) + ((xh*yl > pow(2, 64)-1 - yh*xl) * 0x100000000));
}




long long  __OVERLOADABLE__ mul_hi(long long x, long longy)
{
    ulong lowHalf;
long long highSigned;
    long long testValueA = (long long)x;
long long testValueB = (long long)y;


multiply_signed_64_by_64( testValueA, testValueB, &lowHalf, &highSigned ); 
return highSigned;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值