如何以移位运算来实现乘除法呢?

liyaobinRyan 2011-03-18 09:55:23
如题啊,只能用移位运算(左移与右移)与加减法来实现每乘除法?如果是2的的n次幂就比较容易实现。但是如N/6,N/10,N*6,N*10等运算是如何实现的呢?
...全文
1487 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
hackbuteer1 2011-08-30
  • 打赏
  • 举报
回复
右移一位就是除以2,左移一位就是乘以2。。。。。
cuolelabuyaoa 2011-08-29
  • 打赏
  • 举报
回复
高人啊,大家还在琢磨,就给出程序了!!
fellatioyzx 2011-04-28
  • 打赏
  • 举报
回复

// Bit Operation Implements Add, Submit, Multiply, Divide
// Use only Integer with little length

#include <iostream>
using namespace std;

// add
int add( int a, int b ){
int c;
while( c = (a&b) ){
a = (a^b);
b = (c<<1);
}
return (a^b);
}

// complementary code
int rev( int a ){
return add((~a), 1);
}

// is positive
int ispos( int a ){
return (a&0xFFFF) && !(a&0x8000);
}

// is negative
int isneg( int a ){
return a&0x8000;
}

// is 0
int iszero( int a ){
return !(a&0xFFFF);
}

// if or not have a > b >= 0
int isbig_pos( int a, int b ){
int c = 1;
b = (a^b);
if( iszero(b) ) return 0;
while( b >>= 1 ){
c <<= 1;
}
return (c&a);
}

// if or not have a > b
int isbig( int a, int b ){
if( isneg(a) ){
if( isneg(b) ){
return isbig_pos( rev(b), rev(a) );
}
return 0;
}
if( isneg(b) ) return 1;
return isbig_pos(a, b);
}

// submit
int sub( int a, int b ){
return add(a, rev(b));
}

// two positive numbers multiply
int pos_mul( int a, int b ){
int c = 0x8000;
int re = a;
while( (c>>=1) && (!(b&c)) );
while( c >>= 1 ){
re <<= 1;
if( c&b )
re = add(re, a);
}
return re;
}

// multiply
int mul( int a, int b ){
if( iszero(a) || iszero(b) ) return 0;
if( ispos(a) && ispos(b) )
return pos_mul(a, b);
if( isneg(a) ){
if( isneg(b) ){
return pos_mul( rev(a), rev(b) );
}
return rev( pos_mul( rev(a), b ) );
}
return rev( pos_mul(a, rev(b)) );
}

// two positive numbers divide
int pos_div( int a, int b ){
int re = 0, temp = b;
if( isbig_pos(b, a) ) return 0;
do{
temp <<= 1;
}while( !isbig_pos(temp, a) );
while( isbig_pos(temp, b) ){
re <<= 1;
temp >>= 1;
if( !isbig_pos(temp, a) ){
a = sub(a, temp);
re = add(re, 1);
}
}
return re;
}

// divide
int idiv( int a, int b ){
if( iszero(b) ) {
cout << "error" << endl;
exit(1);
}
if( iszero(a) ) return 0;
if( ispos(a) ){
if( ispos(b) )
return pos_div(a, b);
return rev( pos_div( a, rev(b)) );
}
if( ispos(b) )
return rev( pos_div( rev(a), b ) );
return pos_div( rev(a), rev(b) );
}

int main () {
int a, b;
while( cin >> a >> b){
if(isbig(a,b)&&(a<=b)) cout << "big error" << endl;
if(add(a,b) != (a+b)) cout << "add error" << endl;
if(sub(a,b) != (a-b)) cout << "sub error" << endl;
if(mul(a,b) != (a*b)) cout << "mul error" << endl;
if(idiv(a,b) != (a/b)) cout << "div error" << endl;
}
return 0;
}
寻找Python之禅 2011-03-20
  • 打赏
  • 举报
回复
N*6 = N << 2 + N << 1
buyue__ 2011-03-19
  • 打赏
  • 举报
回复
建议楼主还是不要搞其他数的乘除法,没什么意义。2的n次幂的确比较容易实现,比如右移一位就是除以2,左移一位就是乘以2。。。。。
liuintermilan 2011-03-19
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 zhengjiankang 的回复:]

引用 5 楼 liyaobinryan 的回复:

我看了,但还是不明白,敢问楼上。N/6如何实现呢?能给出解法吗?


不考虑优化的。整数除法:
C/C++ code
int num1 = "input", num2 = 6;

int result = 0;
int remain = num1;
int num3 = num2;
int ……
[/Quote]
楼上兄弟的代码有点问题,比如执行30/6的时候得到的商是4 余数是 6,我给改了下

int num1 = 170, num2 = 13;

int result = 0; //商
int remain = num1; //余数
int num3 = num2;
int temp = 1;

while (num3 < num1)
{
num3 = num3 << 1;
temp = temp << 1;
}

if (num3 > num1)
{
num3 = num3 >> 1;
temp = temp >> 1;
}

while (remain > num2)
{
remain -= num3;
result += temp;
num3 = num3 >> 1;
temp = temp >> 1;

while (num3 > remain)
{
num3 = num3 >> 1;
temp = temp >> 1;
}
}

if (remain == num2)
{
++result;
remain = 0;
}
printf("%d / %d = %d ... %d\n", num1, num2, result, remain);


不过,这个方法只是用移位最大化每次能从被除数中减去除数的数目。
实际中,感觉快不了太多吧。
zhengjiankang 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 liyaobinryan 的回复:]

我看了,但还是不明白,敢问楼上。N/6如何实现呢?能给出解法吗?
[/Quote]

不考虑优化的。整数除法:
	int num1 = "input", num2 = 6;

int result = 0;
int remain = num1;
int num3 = num2;
int temp = 1;

while (num3 < num1)
{
num3 = num3 << 1;
temp = temp << 1;
}

if (num3 > num1)
{
num3 = num3 >> 1;
temp = temp >> 1;
}

while (remain > num2)
{
remain -= num3;
result += temp;
num3 = num3 >> 1;
temp = temp >> 1;

while (num3 > remain)
{
num3 = num3 >> 1;
temp = temp >> 1;
}
}
liuintermilan 2011-03-18
  • 打赏
  • 举报
回复
我也求答案。。
91program 2011-03-18
  • 打赏
  • 举报
回复
乘法,还好说
如果是除法,除不尽的情况,更复杂
liyaobinRyan 2011-03-18
  • 打赏
  • 举报
回复
我看了,但还是不明白,敢问楼上。N/6如何实现呢?能给出解法吗?
無_1024 2011-03-18
  • 打赏
  • 举报
回复
看看计算机组成吧 移位想减除法的实现
liyaobinRyan 2011-03-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 liuintermilan 的回复:]

n*6,先保存个n,左移两位(*4),再加上两个n。
其他的也是类似吧
[/Quote]
那除法呢?N/6,我还有有点不懂除法怎么算
liuintermilan 2011-03-18
  • 打赏
  • 举报
回复
n*6,先保存个n,左移两位(*4),再加上两个n。
其他的也是类似吧

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧