7 个解决方案
#1
怎么来用位操作实现64位数的加法和减法?
--------------------------------------
用位操作来实现二进制数的加减法?这个到是没听说过,二进制数的加减不是有它的运算规则吗?
加法运算 减法运算
1 + 0 = 1 1 - 0 = 1
1 + 1 =0 (进位1) 1 - 1 = 0
0 + 0 = 0 0 - 0 = 0
0 + 1 = 1 0 - 1 = 1 (借位1)
机器里面的加减已经是最简单的运算了。
--------------------------------------
用位操作来实现二进制数的加减法?这个到是没听说过,二进制数的加减不是有它的运算规则吗?
加法运算 减法运算
1 + 0 = 1 1 - 0 = 1
1 + 1 =0 (进位1) 1 - 1 = 0
0 + 0 = 0 0 - 0 = 0
0 + 1 = 1 0 - 1 = 1 (借位1)
机器里面的加减已经是最简单的运算了。
#2
现在的CPU应该有专门实现64位整形运算的机器指令,
这里只给出一个用两个32位整形实现64位整形加减法例子,没有经过测试,可能有错误。
typedef struct { unsigned int high, low; } int64;
// a + b
int64 add(int64 a, int64 b)
{
int64 result;
unsigned int n;
result.low = (a.low & 0x7fffffff) + (b.low & 0x7fffffff); // 防止溢出
// 考虑进位
n = (result.low & 0x80000000) + (a.low & 0x80000000) + (b.low & 0x80000000);
result.low = (result.low & 0x7fffffff) | (n & 0x1)<<31;
result.high = a.high + b.high + (n & 0x2);
return result;
}
// a - b
// 对b取补码后,调用加法运算
int64 sub(int64 a, int64 b)
{
int64 tmp;
tmp.low = ~b.low;
tmp.high = ~b.high;
if (tmp.low != 0xffffffff)
tmp.low += 1;
else {
tmp.low = 0;
tmp.high += 1;
}
return add(a, tmp);
}
这里只给出一个用两个32位整形实现64位整形加减法例子,没有经过测试,可能有错误。
typedef struct { unsigned int high, low; } int64;
// a + b
int64 add(int64 a, int64 b)
{
int64 result;
unsigned int n;
result.low = (a.low & 0x7fffffff) + (b.low & 0x7fffffff); // 防止溢出
// 考虑进位
n = (result.low & 0x80000000) + (a.low & 0x80000000) + (b.low & 0x80000000);
result.low = (result.low & 0x7fffffff) | (n & 0x1)<<31;
result.high = a.high + b.high + (n & 0x2);
return result;
}
// a - b
// 对b取补码后,调用加法运算
int64 sub(int64 a, int64 b)
{
int64 tmp;
tmp.low = ~b.low;
tmp.high = ~b.high;
if (tmp.low != 0xffffffff)
tmp.low += 1;
else {
tmp.low = 0;
tmp.high += 1;
}
return add(a, tmp);
}
#3
从汇编角度来看,64位的加减法需要64位的寄存器,现在一般的机器是32位的(像eax,ebx等)
按2楼做法是可取的,就是要考虑一个进位问题
按2楼做法是可取的,就是要考虑一个进位问题
#4
SSE 128位寄存器 xmm0 - xmm7
#5
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER
typedef __int64 lld;
#define lldfmt "%I64d"
#define llddef( x ) x ## i64
#else
typedef long long lld;
#define lldfmt "%lld"
#define llddef( x ) x ## ll
#endif
lld lld_add( lld a , lld b )
{
lld c ;
while( (c=a&b) != 0 )
a ^= b , b = c << 1 ;
return a | b;
}
int main()
{
lld a = llddef( 221234567890 ) , b = llddef( 111234567890 );
printf( lldfmt " + " lldfmt " == " lldfmt "\n" , a , b , lld_add( a , b ) );
return 0;
}
#include <stdlib.h>
#ifdef _MSC_VER
typedef __int64 lld;
#define lldfmt "%I64d"
#define llddef( x ) x ## i64
#else
typedef long long lld;
#define lldfmt "%lld"
#define llddef( x ) x ## ll
#endif
lld lld_add( lld a , lld b )
{
lld c ;
while( (c=a&b) != 0 )
a ^= b , b = c << 1 ;
return a | b;
}
int main()
{
lld a = llddef( 221234567890 ) , b = llddef( 111234567890 );
printf( lldfmt " + " lldfmt " == " lldfmt "\n" , a , b , lld_add( a , b ) );
return 0;
}
#6
减法..
lld lld_sub( lld a , lld b )
{
return lld_add ( lld_add( a , ~b ) , 1 );
}
lld lld_sub( lld a , lld b )
{
return lld_add ( lld_add( a , ~b ) , 1 );
}
#7
to mLee79:
这样效率是不是也太慢了啊?为了做加减法,还需要使用一个循环?
这样效率是不是也太慢了啊?为了做加减法,还需要使用一个循环?
#1
怎么来用位操作实现64位数的加法和减法?
--------------------------------------
用位操作来实现二进制数的加减法?这个到是没听说过,二进制数的加减不是有它的运算规则吗?
加法运算 减法运算
1 + 0 = 1 1 - 0 = 1
1 + 1 =0 (进位1) 1 - 1 = 0
0 + 0 = 0 0 - 0 = 0
0 + 1 = 1 0 - 1 = 1 (借位1)
机器里面的加减已经是最简单的运算了。
--------------------------------------
用位操作来实现二进制数的加减法?这个到是没听说过,二进制数的加减不是有它的运算规则吗?
加法运算 减法运算
1 + 0 = 1 1 - 0 = 1
1 + 1 =0 (进位1) 1 - 1 = 0
0 + 0 = 0 0 - 0 = 0
0 + 1 = 1 0 - 1 = 1 (借位1)
机器里面的加减已经是最简单的运算了。
#2
现在的CPU应该有专门实现64位整形运算的机器指令,
这里只给出一个用两个32位整形实现64位整形加减法例子,没有经过测试,可能有错误。
typedef struct { unsigned int high, low; } int64;
// a + b
int64 add(int64 a, int64 b)
{
int64 result;
unsigned int n;
result.low = (a.low & 0x7fffffff) + (b.low & 0x7fffffff); // 防止溢出
// 考虑进位
n = (result.low & 0x80000000) + (a.low & 0x80000000) + (b.low & 0x80000000);
result.low = (result.low & 0x7fffffff) | (n & 0x1)<<31;
result.high = a.high + b.high + (n & 0x2);
return result;
}
// a - b
// 对b取补码后,调用加法运算
int64 sub(int64 a, int64 b)
{
int64 tmp;
tmp.low = ~b.low;
tmp.high = ~b.high;
if (tmp.low != 0xffffffff)
tmp.low += 1;
else {
tmp.low = 0;
tmp.high += 1;
}
return add(a, tmp);
}
这里只给出一个用两个32位整形实现64位整形加减法例子,没有经过测试,可能有错误。
typedef struct { unsigned int high, low; } int64;
// a + b
int64 add(int64 a, int64 b)
{
int64 result;
unsigned int n;
result.low = (a.low & 0x7fffffff) + (b.low & 0x7fffffff); // 防止溢出
// 考虑进位
n = (result.low & 0x80000000) + (a.low & 0x80000000) + (b.low & 0x80000000);
result.low = (result.low & 0x7fffffff) | (n & 0x1)<<31;
result.high = a.high + b.high + (n & 0x2);
return result;
}
// a - b
// 对b取补码后,调用加法运算
int64 sub(int64 a, int64 b)
{
int64 tmp;
tmp.low = ~b.low;
tmp.high = ~b.high;
if (tmp.low != 0xffffffff)
tmp.low += 1;
else {
tmp.low = 0;
tmp.high += 1;
}
return add(a, tmp);
}
#3
从汇编角度来看,64位的加减法需要64位的寄存器,现在一般的机器是32位的(像eax,ebx等)
按2楼做法是可取的,就是要考虑一个进位问题
按2楼做法是可取的,就是要考虑一个进位问题
#4
SSE 128位寄存器 xmm0 - xmm7
#5
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER
typedef __int64 lld;
#define lldfmt "%I64d"
#define llddef( x ) x ## i64
#else
typedef long long lld;
#define lldfmt "%lld"
#define llddef( x ) x ## ll
#endif
lld lld_add( lld a , lld b )
{
lld c ;
while( (c=a&b) != 0 )
a ^= b , b = c << 1 ;
return a | b;
}
int main()
{
lld a = llddef( 221234567890 ) , b = llddef( 111234567890 );
printf( lldfmt " + " lldfmt " == " lldfmt "\n" , a , b , lld_add( a , b ) );
return 0;
}
#include <stdlib.h>
#ifdef _MSC_VER
typedef __int64 lld;
#define lldfmt "%I64d"
#define llddef( x ) x ## i64
#else
typedef long long lld;
#define lldfmt "%lld"
#define llddef( x ) x ## ll
#endif
lld lld_add( lld a , lld b )
{
lld c ;
while( (c=a&b) != 0 )
a ^= b , b = c << 1 ;
return a | b;
}
int main()
{
lld a = llddef( 221234567890 ) , b = llddef( 111234567890 );
printf( lldfmt " + " lldfmt " == " lldfmt "\n" , a , b , lld_add( a , b ) );
return 0;
}
#6
减法..
lld lld_sub( lld a , lld b )
{
return lld_add ( lld_add( a , ~b ) , 1 );
}
lld lld_sub( lld a , lld b )
{
return lld_add ( lld_add( a , ~b ) , 1 );
}
#7
to mLee79:
这样效率是不是也太慢了啊?为了做加减法,还需要使用一个循环?
这样效率是不是也太慢了啊?为了做加减法,还需要使用一个循环?