zoukankan      html  css  js  c++  java
  • A+B问题扩展

    A+B  

      要求为给出两个整数a和b, 求他们的和, 但不能使用 + 等数学运算符。在这里我进行了扩展,增加了乘法功能,加法功能是通过检测的,至于乘法功能,我自己测了几组数据是没问题的,至于存不存在漏洞,我也不好说,仅供参考吧。

    package com.zhao.project;
    
    public class Project_1 {
    
        public static void main(String[] args) {
            Project_1 project = new Project_1();
            int sum = project.aplusb(6, -1);
            System.out.println("sum: " + sum);
            sum=project.chengfa(-1, 3);
            System.out.println("result: "+sum);
        }
    
        /*
         * param a: The first integer param b: The second integer return: The sum of
         * a and b
         */
        public int aplusb(int a, int b) {
            /*
             * 按位与 & 二者都为1,结果才是1 否则都为0。 按位或| 二者都为0,结果才是0 否则都为1。 按位异或^ 相同为0 相反为1
             */
            int c = a & b;
            if (c != 0) {
                a = a ^ c;
                b = b ^ c;
                c = c << 1;
                int result = aplusb(a | b, c);
                return result;
            } else {
                return a | b;
            }
    
        }
        public int chengfa(int a,int b){
            int c=0;
            int sum=0;
            for(int i=0;i<31;i++){
                c=b&1;
                if(c!=0){
                    sum=aplusb(a<<i, sum);
                }
                b=b>>1;
            }
            return sum;
        }
    
    }

    加法分析:

      位运算总共只有5种运算:与、或、异或、左移、右移,  按位与 & 二者都为1,结果才是1 否则都为0。 按位或| 二者都为0,结果才是0 否则都为1。 按位异或^ 相同为0 相反为1。左移运算符m<<n表示吧m左移n位。左移n位的时候,最左边的n位将被丢弃,同时在最右边补上n个0。右移运算符m>>n表示把m右移n位。右移n位的时候,最右边的n位将被丢弃。

      我在做加法的时候首先用了6+1,6=0110,1=0001,显然二者按位或,为0111,结果是正确的。可是如果是6+3,即0110+0011,一存在进位问题就失败了。要想做好这个加法 最重要的就是解决这个进位问题。  0 1 1 0  0 0 1 1c=a&b=0010 我们需要把结果第三位设置为0,然后在第二位上加1.显然我们是在a|b=0111的基础上操作的。a^c=得到a中除了需要进位那一位其余的数,b^c得到了b中其余的数。此时的a和b显然是没有同时为1的位的。这样就很方便a|b来得到结果,目前的结果是0101,如愿以偿的把第三位设置为0了。还需要完成进位 也就是 0101+0100,我们有0010,是通过最开始的a&b得到的,能显示的看出来是第三位,要想知道在哪一位上+1 ,c=c<<1;得到的c是0100,接下来我们的问题就是0101+0100了,显然第二位上又是两1,问题重复了,好吧,递归来了。我们接着处理这两个数,当成a和b ,只有a和b完成没有相同位为1的时候,我们用a|b得到结果才可以。 

    乘法分析:
      还是0110 和 0011
       0 1 1 0
    * 0 0 1 1
      0 1 1 0
    0 1 1 0
    1 0 0 1 0
    在纸上进行过这个运算,才觉得和加法好像啊。思路更清晰了,就是好几个数加在一起。a=0110 b=0011,我们只需要得到b的每一位,不是0 就是1 ,有一个1就加一个0110,是0就不加了。但是 需要注意的是,0110后面会补0 补多少0得看情况。
    既然是累加,肯定有sum=0,b除了符号位,应该有31位,好,循环31次,依次得到b的每一位。c=b&1;这样就把b前面清零了,只有最后一位。如果为1 a左移之后加上sum。为什么左移,可以看看乘法的式子,是有一个往左走的过程,所以当i=0时,也就是第一次,是不左移的,也可以说左移为0.以后每次依次左移相应的位数,幸好我们有i这个变量,可以轻松的实现这一过程。不管c是0还是1 b都需要右移,而且每次移动一位,这样才能确保,我们通过读b的最后一位可以把b这个32位的正数都读完,当然 读31位就够了。加法的过程思路和上面一样。 
  • 相关阅读:
    经典数字信号处理图书的个人评述
    信号与系统
    FFT结果的物理意义
    如何选导师,如何做好研究生,如何做好同行评审
    Google学术指数2015版
    2015影响因子Excel版
    VHDL MOD和REM(转)
    面向对象的三大特征
    【数据结构与算法】内部排序之一:插入排序和希尔排序的N中实现(不断优化,附完整源码)
    JAVA字符串String、StringBuffer、StringBuilder、基本数据类型包装
  • 原文地址:https://www.cnblogs.com/zhao307/p/5399425.html
Copyright © 2011-2022 走看看