不使用比较运算符如何比较两个数的大小

前言

今天在水群的过程中看到有位群员谈论到这个话题,是他找工作过程中某家公司的面试题(到底是哪家公司才会出这种没营养的题目刁难别人),有点兴趣,就开始写了。

开搞

想了一下,其实就是题目怪了一点,难度其实并不高。这个题目让我想起了前两年看到的题目,只给你加法,怎么计算加减乘除(都说了到底是哪家公司才会出这种没营养的题目)。相比起来,这题好歹是考了计算机中的加法器,而本文主题中谈论的题目则真的是毫无营养。

思路其实很明显,位运算,这类题目一般都是要用位运算的。这里需要使用到无符号右移。

首先,既然不允许直接比较,那我就相减嘛,a-b结果是0就是相等,结果是负数就是a小,结果是正数那就是a大。

当然这里是不能直接比较结果的正负的, 这样依然不符合提议,怎么办呢。

一切的运算在计算机中都是二进制,数字也是用二进制表示的,而二进制表示数字的时候,最高位是代表符号位,1是负数,0是正数,传统的int最高32位。因此我们只需要判断第32位的结果是0还是1就能判断谁大谁小。直接判断第32位肯定不现实,这里就需要使用到无符号右移运算符“>>>”。举个简单的例子,下面这串二进制只需要无符号右移31位,就可以得到最高位的值

1000 0010 1101 0100 1101 0001 0010 0011
无符号右移31位后
0000 0000 0000 0000 0000 0000 0000 0001

结果显而易见,最高位降到了最低位,其余位全部变成了0,因此,只要结果是负数,那么进行 >>>31 之后的结果转为十进制就是1,否则为0。

        int a = 10;
        int b = 12;
        int index = (a - b) >>> 31;

这样,我们只需要判断index即可。

那么问题来了,题目要求是不允许判断,该怎么办呢?其实这里可以使用数组,下标为0的地方输出a>=b,为1的地方输出a<b。

完整代码:

    public void test() {
        int a = 10;
        int b = 12;
        int index = (a - b) >>> 31;
        String[] arr = {"a>=b", "a<b"};
        System.out.println(arr[index]);
    }

至此,已经基本可以判断a和b的大小了。但是到这里可以发现,a=b和a>b的情况无法分离,这里我们可以继续思考。

当a=b时,a-b=0,那么数组0下标位置是否可以直接放a=b?接着,我们把上面的index+1,结果就变成了:1下标位置是大于等于,2下标位置是小于。其中,等于的情况已经在0下标位置,因此1下标位置的结果就是a>b了。

String[] arr = {"a=b", "a>b", "a<b"};

分析到这里,思路已经很清晰,首先我们计算a-b,直接作为下标取arr中的数据,如果报错了,说明不是0、1、2的情况,那么就继续按照上面的思路进行位运算,取出1和2下标的值 。

    public void test() {
        int a = 13;
        int b = 12;
        int diff = a - b;
        String[] arr = {"a=b", "a>b", "a<b"};
        try {
            System.out.println(arr[diff]);
        } catch (ArrayIndexOutOfBoundsException e) {
            int index = diff >>> 31;
            System.out.println(arr[index + 1]);
        }
    }

到了这里,程序还存在一个bug,当a-b=2时,该程序的判断结果是有问题的,因此,我们需要把计算结果为2的情况给排除,做法很简单,把diff这个变量进行有符号左移2位的操作即可(如果只移1位,当diff为1时,计算结果是2,不符合题意)。左移2位之后的结果绝对值肯定比2要大,因此也就杜绝了出现下标为2的情况。

最终代码。

public void test() {
    int a = 14;
    int b = 12;
    int diff = (a - b) << 2;
    String[] arr = {"a=b", "a>b", "a<b"};
    try {
        System.out.println(arr[diff]);
    } catch (ArrayIndexOutOfBoundsException e) {
        int index = diff >>> 31;
        System.out.println(arr[index + 1]);
    }
}

最后还是要吐槽一句,没事别出这种没营养的面试题刁难人家啦!

如果你觉得该博客对你有帮助,不放动动手指加一下交流群。

发布了35 篇原创文章 · 获赞 45 · 访问量 6134

猜你喜欢

转载自blog.csdn.net/qq_36403693/article/details/105409625