zoukankan      html  css  js  c++  java
  • 算法-位运算-1

    1. 不用比较判断找出AB中较大的数

     1 public class getMaxWithOutCompair {
     2     public int flip(int n) {
     3         return n ^ 1;
     4     }
     5 
     6     public int sign(int n) {
     7         // 如果负数返回0 如果正数返回1
     8         return flip((n >> 31) & 1);
     9     }
    10 
    11     public int getMax(int a, int b) {
          // 这里可能溢出
    12 int c = a - b; 13 int sign = sign(c); 14 int flip = flip(sign); 15 return a * sign + b * flip; 16 } 17 }
     1  public int getMax2(int a, int b) {
     2         int sa = sign(a); // 正数返回1 负数返回0
     3         int sb = sign(b); // 正数返回1 负数返回0
     4         int sc = sign(a - b); // // 正数返回1 负数返回0
     5         int disSab = sa ^ sb; // a 和b的符号不一样返回1 符号一样返回0
     6         int sameSab = flip(disSab); // a 和b的符号不一样返回1 符号一样返回0
     7         int returnA = disSab * sa + sameSab * sc; // a 和b的符号不一样返回1 a正数返回1 a 
     8         // 和b的符号不一样返回1 正数返回1
     9         int returnB = flip(returnA);
    10         return a * returnA + b * returnB;
    11 
    12     }

    2. 32位的数判断是否是2的幂 4的幂

    2的幂的二进制特性 只有一位上是1其余都是0

    取二进制数上最右的1的位置

    N&((~N)+1) 

    1. 求数的最右1 判断两个数是否相等

    2. 数 & 数-1等于0 说明是2 的幂次方数

    4的幂次方二进制数特征 二进制位上只有一个1,1的位置在0 2 4 6位置上

    4的幂一定是2的幂

    先判断二进制位上只有一个1再

    数 & 0101 0101 0101 0101 0101 0101 0101 0101 (0x55555555)不等于0 是4的幂次方数

    3. 不使用算数运算符 实现a和b的加减乘除

    ^ 代表无进位相加

    & 左移1位代表进位信息

    数取反+1 就是数的反数

     2 
     3 /**
     4  * 不使用运算符 执行加减乘除运算
     5  * <p>
     6  * 加减乘除
     7  * add , subtract , multiply and divide
     8  */
     9 public class MathOperation {
    10 
    11     public int add(int a, int b) {
    12         int i = a;
    13         while (b != 0) {
    14             i = a ^ b; // 无进位相加
    15             b = (a & b) << 1; // 进位信息
    16             a = i;
    17         }
    18         return i;
    19     }
    20 
    21     public int subtract(int a, int b) {
    22         return add(a, negNum(b));
    23     }
    24 
    25     public int negNum(int a) {
    26         return add(~a, 1);
    27     }
    28 
        // 跟十进制乘法一样的思路 只是换成二进制 29 public int multiply(int a, int b) { 30 int res = 0; 31 while (b != 0) { 32 if ((b & 1) != 0) { 33 res = add(res, a); 34 } 35 a <<= 1; 36 b >>>= 1; 37 } 38 return res; 39 } 40 41 public int divide(int a, int b) { 42 int res = 0; 43 for (int i = 31; i > -1; i = subtract(i, 1)) {
              // a >> 1为了避免溢出
    44 if ((a >> i) >= b) {
                // 满足条件说明i位置上可以至为1
    45 res |= (1 << i);
                // a减去b
    46 a = subtract(a, b << i); 47 } 48 } 49 return res; 50 } 51 52 }
  • 相关阅读:
    一些Docker 操作集合
    与Flash 中国特供版斗智斗勇
    Linux 电子数据取证入门
    emu8086实现两位数加法运算
    emu8086实现两位数乘法运算
    5种三栏布局的实现方式
    通用事件绑定方法
    随机产生两个数值之间的某个值
    查询字符串中某个字符出现的位置数组
    根据对象属性的属性值,对对象进行排序
  • 原文地址:https://www.cnblogs.com/isnotnull/p/15071601.html
Copyright © 2011-2022 走看看