首先我们想想位操作符-> ^ (异或)
异或可以相当于无进位相加
同时我们的进位为信息也可以用 (x & y)<<1来表示
那么我么的“+”可以相当于是无进位相加数 + 进位信息。
但是我们模拟实验“+”所以不能出现加号。
什么时候不需要加上进位信息--->进位信息为0的时候。
那么我们就可以知道,位运算实现“+”
- public static int add(int a,int b){
- int x = a>b ? a : b;
- int y = x==a ? b : a;
- int sum = 0;
- while( y!=0 ){
- sum = x ^ y;
- y = (x & y)<<1;
- x = sum;
- }
- return sum;
- }
同时位运算实现减号---->就是
- private static int negNum(int n){
- return add(~n,1);
- }
- public static int minus(int x,int y){
- return add(x,negNum(y));
- }
将y--->进行取反+1就是-y.
x-y = x + (-y);
乘号
首先我们先想想我们是如何实现乘法的

我们先看这个20---。
首先20的第一个数字是0.那么我们用0乘以12所得为零。-------第一阶段结果为0。
其次20的第二个数字为2.那么我们是先将2*12,然后将所得的数字的后面加一个0,------第二阶段的结果为240.
那么我们可以想象,我们所进行的十进位的数字的乘法,实际上的步骤是:
将乘数的第0位数字,单独和被乘数相乘,相乘所得数向前移动0位,然后得到一个阶段的数字
将乘数的第1位数字,单独和被乘数相乘,相乘所得数向前移动1位,然后得到一个阶段的数字
将乘数的第2位数字,单独和被乘数相乘,相乘所得数向前移动2位,然后得到一个阶段的数字
将乘数的第3位数字,单独和被乘数相乘,相乘所得数向前移动3位,然后得到一个阶段的数字
...................
直到乘数的所有非零的数字都进行上诉运算后,然后将所有得到的阶段数字进行相加,就得到乘法所得到的数字。
但是当我们使用到二进制位也是如此。
- public static int muli(int a,int b){
- int sum = 0;
- while(b != 0){
- if((b & 1)!=0){
- sum = add(sum,a);
- }
- a<<=1;
- b>>>=1;
- }
- return sum;
- }
接下来我们说说除法。
我们先了解一下我们平时是如何进行除法运算的。

首先我们十进制的除法运算,是首先从头开始
首先我们先从被除数中重头找到大于除数的数字,然后我们利用那么我们就能够算最大为几倍,然后相减。剩下的数字我们就继续找到,知道我们的被除数小于我们的除数的时候我们就得出结论
- private static int div(int a,int b){
- int x = isNeg(a) ? negNum(a) : a;
- int y = isNeg(b) ? negNum(b) : b;
- int res = 0;
- for(int i = 30;i>=0; i = muli(i,1)){
- if((x>>i)>=y){
- res |= (1<
- x = minus(x, y<< i);
- }
- }
- return isNeg(a) ^ isNeg(b) ? negNum(res) : res;
- }
同时我们还是有一个问题需要我们来考虑,就是我们的这个类型是一个int类型的。当我们出现Integer.MIN_VALUE---->最小值的时候我们就没有办法转化成正数。那么我们就是需要特殊问题特殊处理了
1.除数和被除数都是Integer.MIN_VALUE----->直接返回1.
2.除数是Integer.MIN_VALUE,被除数不是。------>返回0.
3.除数不是,被除数是---->特殊情况特殊考虑。
4.除数和被除数都不是Integer.MIN_VALUE----->直接调用
特殊情况的讨论:
首先知道系统最小值是的绝对值比系统最大值的绝对值大1.
其次我们的Integer.MIN_VALUE--->无法转成正数,但是我们可以先将Integer.MIN_VALUE+1,这样就可以转成正数,同时我们算出来的余数在加上1,再进行一次除法计算,将两次得到结果相加就是我们特殊情况的处理
- private static int div(int a,int b){
- int x = isNeg(a) ? negNum(a) : a;
- int y = isNeg(b) ? negNum(b) : b;
- int res = 0;
- for(int i = 30;i>=0; i = minus(i,1)){
- if((x>>i)>=y){
- res |= (1<
- x = minus(x, y<< i);
- }
- }
- return isNeg(a) != isNeg(b) ? negNum(res) : res;
- }
- public static int divide(int a,int b){
- if(a == Integer.MIN_VALUE && b==Integer.MIN_VALUE){
- return 1;
- }else if(b == Integer.MIN_VALUE){
- return 0;
- }else if(a == Integer.MIN_VALUE){
- if(b == negNum(1)){
- return Integer.MAX_VALUE;
- }else{
- int c = div(add(a,1),b);
- return add(c,div(minus(a,muli(c,b)),b));
- }
- }else{
- return div(a,b);
- }
- }
-------------------------------------------
- public static int add(int a,int b){
- int x = a>b ? a : b;
- int y = x==a ? b : a;
- int sum = 0;
- while( y!=0 ){
- sum = x ^ y;
- y = (x & y)<<1;
- x = sum;
- }
- return sum;
- }
- private static int negNum(int n){
- return add(~n,1);
- }
- public static int minus(int x,int y){
- return add(x,negNum(y));
- }
- public static int muli(int a,int b){
- int sum = 0;
- while(b != 0){
- if((b & 1)!=0){
- sum = add(sum,a);
- }
- a<<=1;
- b>>>=1;
- }
- return sum;
- }
- private static boolean isNeg(int x){
- return x<0;
- }
- private static int div(int a,int b){
- int x = isNeg(a) ? negNum(a) : a;
- int y = isNeg(b) ? negNum(b) : b;
- int res = 0;
- for(int i = 30;i>=0; i = minus(i,1)){
- if((x>>i)>=y){
- res |= (1<
- x = minus(x, y<< i);
- }
- }
- return isNeg(a) != isNeg(b) ? negNum(res) : res;
- }
- public static int divide(int a,int b){
- if(a == Integer.MIN_VALUE && b==Integer.MIN_VALUE){
- return 1;
- }else if(b == Integer.MIN_VALUE){
- return 0;
- }else if(a == Integer.MIN_VALUE){
- if(b == negNum(1)){
- return Integer.MAX_VALUE;
- }else{
- int c = div(add(a,1),b);
- return add(c,div(minus(a,muli(c,b)),b));
- }
- }else{
- return div(a,b);
- }
- }
- private static int mod(int x,int y){
- if((y & (minus(y,1)))==0){
- return x & (minus(y,1));
- }else{
- for(int i = 30;i>=0; i = minus(i,1)){
- if((x>>i)>=y){
- x = minus(x,y<
- }
- }
- return x;
- }
- }
-
相关阅读:
网络基础—网关、网段、子网掩码
1.13.C++项目:仿muduo库实现并发服务器之TcpServer模块的设计
LabVIEW中不同颜色连线的含义
安卓教材学习
SpringBoot+Vue项目中session改变的问题解决
「SpringCloud」08 Config分布式配置中心
python-中断time.sleep一种更优雅的办法:event.wait
Nature发布:ChatGPT 帮助我进行学术写作的三种方式
JS Promise 之 Hello World
数据库审计 - 网络安全的重要组成部分
-
原文地址:https://blog.csdn.net/weixin_61652218/article/details/126327562