当前位置: 首页 > article >正文

大一计算机的自学总结:位运算实现加减乘除

前言

位运算当然可以用来实现加减乘除。

一、加法

#include<bits/stdc++.h>
using namespace std;

int add(int a,int b)
{
	int ans=a;
	while(b!=0)
	{
		ans=a^b;
		b=(a&b)<<1;
		a=ans;
	}
	return ans;
}

int main()
{
	int a,b;
	cout<<"a,b:"<<endl;
	cin>>a>>b;
	
	cout<<add(a,b);
	
	return 0;
}

 加法的原理就是利用了异或运算的本质:无进位加法再加上进位信息所得。

先让ans=a,然后只要b不等于0,先取两数的异或,即无进位加法;之后取两数进位信息,若两数在相同数位上都为1,所以该位进位,就是a&b。然后为了将进位信息加到ans中,要将a&b的的结果左移一位,直到两数没有进位信息。

二、减法

#include<bits/stdc++.h>
using namespace std;

int add(int a,int b)
{
	int ans=a;
	while(b!=0)
	{
		ans=a^b;
		b=(a&b)<<1;
		a=ans;
	}
	return ans;
}

int neg(int n)
{
	return add(~n,1);
}

int sub(int a,int b)
{
	return add(a,neg(b));
}

int main()
{
	int a,b;
	cout<<"a,b:"<<endl;
	cin>>a>>b;
	
	cout<<sub(a,b);
	
	return 0;
}

 减法就很简单了,转化成a+(-b)即可,而-b就是~b+1。

三、乘法

#include<bits/stdc++.h>
using namespace std;

int add(int a,int b)
{
	int ans=a;
	while(b!=0)
	{
		ans=a^b;
		b=(a&b)<<1;
		a=ans;
	}
	return ans;
}

int mult(int a,int b)
{
	int ans=0;
	while(b!=0)
	{
		if((b&1)!=0)
		{
			ans=add(ans,a);
		}
		a<<=1;
		b>>=1;
	}
	return ans;
}

int main()
{
	int a,b;
	cout<<"a,b:"<<endl;
	cin>>a>>b;
	
	cout<<mult(a,b);
	
	return 0;
}

 乘法依旧借助了竖式运算的原理,只不过这里是按二进制数位进行的。

若b的最后一位是1,就让ans再加上一个a,之后,要将a左移1位,并且为了取b的下一个数位,要让b右移一位。

四、除法

#include<bits/stdc++.h>
using namespace std;

int add(int a,int b)
{
	int ans=a;
	while(b!=0)
	{
		ans=a^b;
		b=(a&b)<<1;
		a=ans;
	}
	return ans;
}

int neg(int n)
{
	return add(~n,1);
}

int sub(int a,int b)
{
	return add(a,neg(b));
}

int divide(int a,int b)
{
	int x=a<0?neg(a):a;
	int y=b<0?neg(b):b;
	int ans=0;
	for(int i=30;i>=0;i--)
	{
		if((x>>i)>=y)
		{
			ans|=(1<<i);
			x=sub(x,y<<i);
		}
	}
	return (a<0)^(b<0)?neg(ans):ans;
}

int main()
{
	int a,b;
	cout<<"a,b:"<<endl;
	cin>>a>>b;
	
	cout<<divide(a,b);
	
	return 0;
}

除法借助的原理是,例如280除以25,只保留商,可以将280转化成25*2^3+25*2^1+25*2^0。

首先先将负数转为正数,然后从第30位开始到第0位,若x右移i位比y大,即x还包含2^i个y,所以往ans的第i位里或进去一个1,之后让x减去2^i个y即可。最后这个判断很妙,只有a和b异号时才返回-ans。

总结

感觉位运算实现加减乘除在做题上没什么用,就当训练位运算了。()

END


http://www.kler.cn/a/526512.html

相关文章:

  • 智慧园区系统助力企业智能化升级实现管理效率与安全性全方位提升
  • 【Pandas】pandas Series cumsum
  • https数字签名手动验签
  • C动态库的生成与在Python和QT中的调用方法
  • OpenEuler学习笔记(十七):OpenEuler搭建Redis高可用生产环境
  • vue3中customRef的用法以及使用场景
  • 用BGP的路由聚合功能聚合大陆路由,效果显著不?
  • rust如何操作sqlserver
  • 每日 Java 面试题分享【第 17 天】
  • 18、智能驾驶芯片外部接口要求
  • SpringBoot中运行Yolov5程序
  • 前端知识速记—JS篇:null 与 undefined
  • Linux实操篇-文件目录类>/>>/echo/head/tail/ln/history
  • leetcode-分割等和子集
  • Java中 instanceof 的用法(详解)
  • 安卓(android)饭堂广播【Android移动开发基础案例教程(第2版)黑马程序员】
  • 谭浩强C语言程序设计(4) 8章(上)
  • deepseek R1 14b显存占用
  • 【Block总结】HWD,小波下采样,适用分类、分割、目标检测等任务|即插即用
  • 【Block总结】CAA捕获远程上下文信息,增强特征提取的能力|即插即用
  • 哈希表实现
  • 缓冲区和c库的简单实现
  • 性能优化2-删除无效引用
  • kobject、kset和ktype的关系
  • 论文阅读(七):贝叶斯因果表型网络解释遗传变异和生物学知识
  • python | OpenCV小记(一):cv2.imread(f) 读取图像操作(待更新)