首先我们想想位操作符-> ^ (异或)
异或可以相当于无进位相加
同时我们的进位为信息也可以用 (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;
- }
- }
-
相关阅读:
手撕Vuex-实现actions方法
vue+elementUI el-select 自定义搜索逻辑(filter-method)
深度学习简述
现代GPGPU 架构汇总
1155掷骰子等于目标和的方法数 (dfs + 记忆化搜索)
关于vue封装form表单单向流数据问题
JavaScript 中 toString 的奇妙使用
一文彻底搞懂Mybatis系列(十二)之MyBatis多对一映射延迟加载(association和lazyLoadingEnabled)
CentOS8挂载本地ISO 配置本地YUM源
机器学习中的数学原理——梯度下降法(最速下降法)
-
原文地址:https://blog.csdn.net/weixin_61652218/article/details/126327562