zoukankan      html  css  js  c++  java
  • 一道位运算的题目

    题目来自:求最大数值

    编写一个方法,找出两个数字a和b中最大的那一个。
    不得使用if-else或其他比较运算符。
    
    示例:
    
    输入: a = 1, b = 2
    输出: 2
    

    思路分析:

    短路特性 + 位运算

    条件运算符是具有短路特性的,当前面条件不满足时,后面就不会继续运算。所有可以使用短路特性来代替if判断条件。
    判断两个数的大小关系,先作差,然后判断最高位的符号的正负即可。位运算要考虑溢出的情况,所以需要考虑同号和异号两种情况。

    int maximum(int a, int b) {
    	int res = a;
    	//异号处理
    	(a ^ b) >> 31 && (a >> 31) && (res = b);
    	//同号处理
    	(-(a ^ b) >> 31) && ((a - b) >> 31) && (res = b);
    	return res;
    }
    

    异或运算

    1. 首先我们目标是得到一个标志ans,当a大的时候ans为1,b大的时候ans为0。如果我们能得到ans,则最终的答案是 ans * a + (ans ^ 1) * b;这里异或1的操作,把0变成1,把1变成0。

    2. 如何得到ans,容易想到的是拿到b-a的符号位,但整数溢出会导致符号位不可靠。所以我们还需要拿到a和b的符号位,如果a,b同号,则相减不会溢出,如果异号,则直接选择非负的那个(即符号位为0)的即可。注:32位整型的符号位可以通过将原数右移31位得到。

    3. 以下记a的符号位为x,b的符号位为y,b-a的符号位为z。
      得到下列真值表:

    x y z ans
    0 0 0 0
    0 0 1 1
    0 1 0 1
    0 1 1 1
    1 0 0 0
    1 0 1 0
    1 1 0 0
    1 1 1 1

    通过真值表,使用卡诺图求出ans的表达式。有点类似于数字电路的思想。
    根据从真值表求表达式,以及卡诺图相关知识,可以得到公式:
    ans = (!x & y) | (!x & z) | (y & z);
    注:这里!代表逻辑非,代码实现中应当使用(x ^ 1)代替比较好。
    因为只用到了非x,以下代码中的x直接就是这里的(x ^ 1)

    int maximum(int a, int b) {
    	unsigned aa = a, bb = b;
    	bool x = (aa >> 31) ^ 1, y = bb >> 31, z = (bb - aa) >> 31;
    	bool ans = (x & y) | (x & z) | (y & z);
    	return ans * a + (ans ^ 1) * b;
    }
    

    另外一种方法:

    1. int计算溢出的情况可以转化为long long计算。
    2. 取出符号位可以通过位移获得。

    实现如下

    int maximum(int a, int b) {
    	long k = (((long)a - (long)b) >> 63) & 1;
    	return b * k + a * (k ^ 1);
    }
    

    最好把输入的a和b强行转成无符号整型再计算,否则leetcode的编译器不让做越界的减法运算。

    数学方法

    利用数学上的公式:

    max(a, b) = ((a + b) + abs(a - b)) / 2
    

    为了回避abs,利用位运算实现绝对值功能:
    也可以考虑先平方,再开方来求得绝对值。但是存在大数超出表示范围的情况,可能需要转成double值运算,或者使用数组来做大数乘法。

    abs(var) = (var ^ (var >> 63)) - (var >> 63)
    

    或者

    long absolute(long a) {
    	int flag = a >> 63; //正数flag = 0,负数flag = -1
    	return (flag ^ a) - flag; //任何数与0异或值不变,任何数与-1异或等价于按位取反
    }
    
  • 相关阅读:
    创造别人想要的东西(2)----创业15问
    创造别人想要的东西(1)----创业的本质
    有点迷茫
    普林斯顿大学算法公开课(1)----介绍
    工业控制系统信息安全与信息安全、功能安全的区别【转自工控工程网】
    十条概念区分信息安全与隐私保护【转自安全牛】
    NBT(NetBIOS Over TCP)名称解析概述
    SMB协议概述
    PCI DSS合规建设ASV扫描介绍
    信息安全等级测评师(初级 技术)
  • 原文地址:https://www.cnblogs.com/shijiashuai/p/14417628.html
Copyright © 2011-2022 走看看