• 位运算的应用----->实现加减乘除


    首先我们想想位操作符->  ^ (异或)

    异或可以相当于无进位相加

    同时我们的进位为信息也可以用 (x & y)<<1来表示

    那么我么的“+”可以相当于是无进位相加数 + 进位信息。

    但是我们模拟实验“+”所以不能出现加号。

    什么时候不需要加上进位信息--->进位信息为0的时候。

    那么我们就可以知道,位运算实现“+”

    1. public static int add(int a,int b){
    2. int x = a>b ? a : b;
    3. int y = x==a ? b : a;
    4. int sum = 0;
    5. while( y!=0 ){
    6. sum = x ^ y;
    7. y = (x & y)<<1;
    8. x = sum;
    9. }
    10. return sum;
    11. }

    同时位运算实现减号---->就是

    1. private static int negNum(int n){
    2. return add(~n,1);
    3. }
    4. public static int minus(int x,int y){
    5. return add(x,negNum(y));
    6. }

    将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位,然后得到一个阶段的数字

    ...................

    直到乘数的所有非零的数字都进行上诉运算后,然后将所有得到的阶段数字进行相加,就得到乘法所得到的数字。

    但是当我们使用到二进制位也是如此。

    1. public static int muli(int a,int b){
    2. int sum = 0;
    3. while(b != 0){
    4. if((b & 1)!=0){
    5. sum = add(sum,a);
    6. }
    7. a<<=1;
    8. b>>>=1;
    9. }
    10. return sum;
    11. }

    接下来我们说说除法。

    我们先了解一下我们平时是如何进行除法运算的。

    首先我们十进制的除法运算,是首先从头开始

    首先我们先从被除数中重头找到大于除数的数字,然后我们利用那么我们就能够算最大为几倍,然后相减。剩下的数字我们就继续找到,知道我们的被除数小于我们的除数的时候我们就得出结论

    1. private static int div(int a,int b){
    2. int x = isNeg(a) ? negNum(a) : a;
    3. int y = isNeg(b) ? negNum(b) : b;
    4. int res = 0;
    5. for(int i = 30;i>=0; i = muli(i,1)){
    6. if((x>>i)>=y){
    7. res |= (1<
    8. x = minus(x, y<< i);
    9. }
    10. }
    11. return isNeg(a) ^ isNeg(b) ? negNum(res) : res;
    12. }

    同时我们还是有一个问题需要我们来考虑,就是我们的这个类型是一个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,再进行一次除法计算,将两次得到结果相加就是我们特殊情况的处理

    1. private static int div(int a,int b){
    2. int x = isNeg(a) ? negNum(a) : a;
    3. int y = isNeg(b) ? negNum(b) : b;
    4. int res = 0;
    5. for(int i = 30;i>=0; i = minus(i,1)){
    6. if((x>>i)>=y){
    7. res |= (1<
    8. x = minus(x, y<< i);
    9. }
    10. }
    11. return isNeg(a) != isNeg(b) ? negNum(res) : res;
    12. }
    13. public static int divide(int a,int b){
    14. if(a == Integer.MIN_VALUE && b==Integer.MIN_VALUE){
    15. return 1;
    16. }else if(b == Integer.MIN_VALUE){
    17. return 0;
    18. }else if(a == Integer.MIN_VALUE){
    19. if(b == negNum(1)){
    20. return Integer.MAX_VALUE;
    21. }else{
    22. int c = div(add(a,1),b);
    23. return add(c,div(minus(a,muli(c,b)),b));
    24. }
    25. }else{
    26. return div(a,b);
    27. }
    28. }

    -------------------------------------------

    1. public static int add(int a,int b){
    2. int x = a>b ? a : b;
    3. int y = x==a ? b : a;
    4. int sum = 0;
    5. while( y!=0 ){
    6. sum = x ^ y;
    7. y = (x & y)<<1;
    8. x = sum;
    9. }
    10. return sum;
    11. }
    12. private static int negNum(int n){
    13. return add(~n,1);
    14. }
    15. public static int minus(int x,int y){
    16. return add(x,negNum(y));
    17. }
    18. public static int muli(int a,int b){
    19. int sum = 0;
    20. while(b != 0){
    21. if((b & 1)!=0){
    22. sum = add(sum,a);
    23. }
    24. a<<=1;
    25. b>>>=1;
    26. }
    27. return sum;
    28. }
    29. private static boolean isNeg(int x){
    30. return x<0;
    31. }
    32. private static int div(int a,int b){
    33. int x = isNeg(a) ? negNum(a) : a;
    34. int y = isNeg(b) ? negNum(b) : b;
    35. int res = 0;
    36. for(int i = 30;i>=0; i = minus(i,1)){
    37. if((x>>i)>=y){
    38. res |= (1<
    39. x = minus(x, y<< i);
    40. }
    41. }
    42. return isNeg(a) != isNeg(b) ? negNum(res) : res;
    43. }
    44. public static int divide(int a,int b){
    45. if(a == Integer.MIN_VALUE && b==Integer.MIN_VALUE){
    46. return 1;
    47. }else if(b == Integer.MIN_VALUE){
    48. return 0;
    49. }else if(a == Integer.MIN_VALUE){
    50. if(b == negNum(1)){
    51. return Integer.MAX_VALUE;
    52. }else{
    53. int c = div(add(a,1),b);
    54. return add(c,div(minus(a,muli(c,b)),b));
    55. }
    56. }else{
    57. return div(a,b);
    58. }
    59. }
    60. private static int mod(int x,int y){
    61. if((y & (minus(y,1)))==0){
    62. return x & (minus(y,1));
    63. }else{
    64. for(int i = 30;i>=0; i = minus(i,1)){
    65. if((x>>i)>=y){
    66. x = minus(x,y<
    67. }
    68. }
    69. return x;
    70. }
    71. }
  • 相关阅读:
    网络基础—网关、网段、子网掩码
    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