原帖请见:看到一个面试题,大家来讨论下!
因为那个帖子太长了,我结了。这个帖子里主要贴几个典型的解法。我认为比较好的解法(在Blog里也写了这个方法:不用比较运算符,判断int型的a,b两数的大小
public class Bigger {
public static void main(String args[]){
int a = -2147483648;
int b = 2147483647;

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

int i = (int)((long)a-(long)b >>> 63);

System.out.println(strArray[i]);
}
}
然后我在回帖中看到了几个很典型的方法(注意:不用比较运算符,不用类库方法。)
System.out.println(a-b);  //无语,那还不如int a=1; int b=2;直接拿眼睛看算了。
if(!(a-b)) 
{     if(abs(a-b)-(a-b))  
    { 
        return "a < b"; 
    } 
    else 
    { 
        return "a > b"; 
    } 

else 

    return "a = b"; 
}//方法很好,数学里整数能到无穷大,但是计算机里不行啊。
public String compare(Integer x,Integer y){ 
  String [] buf={"=>"," <"}; 
  int id1=(x-y)>>>31;  
  System.out.println(id1); 
  return buf[id1]; 
}//也是没有考虑越界问题还有些是用接口实现的,有点复杂了。有很多人会问,搞这个东西有什么实际的用途吗?是,确实没什么用,不如直接比较。但是有时候我们中国人就是被这种“有没有用”的功利主义给害了。研究数学,物理和化学有用吗?是没有直接的作用,但是你看看为什么美国,日本,德国的工业和高科技产业如此发达,还不是靠基础科学的投入吗?Google为了提高搜索算法的效率,也是投入巨资。不是什么东西有用没用就能简单的决定你去不去做一件事情,因为你不去做一件事情,就无法知道你在做这件事情的过程中会有什么收获。有一句话说的好:人生是曲折的,但生活是精彩的。

解决方案 »

  1.   

    借鉴楼主的精彩答案,我这里是一个完整版:
    import java.util.Random;/**
     * 不通过比较运算和类库,比较两个 integer 大小
     */
    public class SimpleCompare {    public static void main(String[] args) {
            Random r = new Random();
            int a = r.nextInt(), b = r.nextInt();
            // int a = 33, b = 33;        String[] results = {"a < b", "a == b", "a > b"};        int sum = 1;
            sum = sum - (int)((long)(a - b) >>> 63);
            sum = sum + (int)((long)(b - a) >>> 63);
            System.out.println(a + ", " + b + ": " + results[sum]);
        }
    }
      

  2.   


    (long)(a-b)这样是不行的,a-b的结果仍然是个int型,然后再去转成long,这时的值可能已经不是想要的了。
      

  3.   

    就是把a和b强制转换成long型的,然后避免了异号两数想减导致的溢出问题。
      

  4.   

        if( (abs(a-b)+abs(a-b)) /2 == a)  
        { 
            System.out.println("a > b"); 
        } 
        else 
        { 
            System.out.println("a < b");
        }分析一下,呵呵
    如果a>b,则|a-b|即为a-b
       则(|a-b|+|a+b|)/2 = (a-b+a+b)/2 = a
    如果a<b,则|a-b|即为b-a
       则(|a-b|+|a+b|)/2 = (b-a+a+b)/2 = b因此(|a-b|+|a+b|)/2总返回二者中的较大者,由此可判断二者的大小
      

  5.   

    我博客里已经写了答案!不用比较运算符,判断int型的a,b两数的大小,考虑溢出问题
      

  6.   

    public class Test5 {    public static void main(String[] args) {
            int a = -2147483648;
            int b = 2147483647;
            System.out.println(max(a, b));
        }    public static int max(int a, int b) {
            int k = (~(a ^ b) >>> 31) * (a - b) >>> 31;
            k += ((a ^ b) >>> 31) * (a >>> 31);
            return b * k + a * (k ^ 1);
        }
    }
      

  7.   

    也写一个玩玩:
    public class Compare {
    private static final boolean signToBool[] = { true, false }; private static final boolean getSignOfInteger(int integer) {
    return signToBool[integer >>> 31];
    } public static boolean compareInteger(int int1, int int2) {
    boolean signOfInt1 = getSignOfInteger(int1);
    boolean signOfInt2 = getSignOfInteger(int2);
    boolean signInt1MinusInt2 = getSignOfInteger(int1 - int2);
    return (!(signOfInt1 ^ signOfInt2) && signInt1MinusInt2)
    || ((signOfInt1 ^ signOfInt2) && signOfInt1);
    }
    }
    测试代码:
    import java.util.Calendar;
    import java.util.Random;import junit.framework.TestCase;public class CompareTest extends TestCase { public void testCompareWithSimpleIntegers() {
    assertTrue(Compare.compareInteger(1, 1));
    assertTrue(Compare.compareInteger(0, 0));
    assertTrue(Compare.compareInteger(-1, -1)); assertTrue(Compare.compareInteger(1, 0));
    assertTrue(Compare.compareInteger(0, -1));
    assertTrue(Compare.compareInteger(2, 1));
    assertTrue(Compare.compareInteger(1, -1));
    assertTrue(Compare.compareInteger(-1, -2)); assertFalse(Compare.compareInteger(0, 1));
    assertFalse(Compare.compareInteger(-1, 0));
    assertFalse(Compare.compareInteger(1, 2));
    assertFalse(Compare.compareInteger(-1, 1));
    assertFalse(Compare.compareInteger(-2, -1));
    } public void testCompareWithLargeIntegers() {
    assertTrue(Compare.compareInteger(Integer.MAX_VALUE, Integer.MAX_VALUE));
    assertTrue(Compare.compareInteger(Integer.MAX_VALUE, 0));
    assertTrue(Compare.compareInteger(Integer.MAX_VALUE, -1));
    assertTrue(Compare.compareInteger(Integer.MAX_VALUE, Integer.MIN_VALUE));
    assertFalse(Compare.compareInteger(0, Integer.MAX_VALUE));
    assertFalse(Compare.compareInteger(-2, Integer.MAX_VALUE)); assertTrue(Compare.compareInteger(Integer.MIN_VALUE, Integer.MIN_VALUE));
    assertFalse(Compare.compareInteger(Integer.MIN_VALUE, 0));
    assertFalse(Compare
    .compareInteger(Integer.MIN_VALUE, Integer.MAX_VALUE));
    assertTrue(Compare.compareInteger(-1, Integer.MIN_VALUE));
    assertTrue(Compare.compareInteger(0, Integer.MIN_VALUE));
    } public void testCompareWithRandomIntegers() {
    Random random = new Random();
    random.setSeed(Calendar.getInstance().getTimeInMillis());
    int countOfTestDatas = 10000;
    for (int i = 0; i < countOfTestDatas; i++) {
    int a = random.nextInt();
    int b = random.nextInt();
    assertEquals(Compare.compareInteger(a, b), a >= b);
    }
    }
    }
      

  8.   

    终于做完了,累死了public class Test5 {    public static void main(String[] args) {        int a = -2147483648;
            int b = 2147483647;        // a 和 b 是否相等,相等时 e 值为 0,否则为 1
            // 采用对半位或,逐次降位进行计算
            int e = a ^ b;
            e = (e & 0xffff0000) >>> 16 | (e & 0x0000ffff);
            e = (e & 0x0000ff00) >>>  8 | (e & 0x000000ff);
            e = (e & 0x0000000f) >>>  4 | (e & 0x0000000f);
            e = (e & 0x0000000c) >>>  2 | (e & 0x00000003);
            e = (e & 0x00000002) >>>  1 | (e & 0x00000001);        // 进行比较,a 大时 k 值为 0,b 大时 k 值为 1,a 和 b 相等时 k 值为 0
            int k = (~(a ^ b) >>> 31) * (a - b) >>> 31;
            k += ((a ^ b) >>> 31) * (a >>> 31);        // 按照 <、=、> 的 ASCII 顺序,修正 ASCII 偏移量
            // e = 0, k = 0 时表示相等,偏移 1
            // e = 1, k = 0 时表示大于,偏移 2
            // e = 1, k = 1 时表示小于,偏移 0
            int offset = (e & (k ^ 1)) + (k ^ 1);        System.out.printf("%d %3$c %2$d%n", a, b, '<' + offset);        // System.out.println(a + " " + (char)('<' + offset) + " " + b);
        }
    }
      

  9.   

    我说我发的怎么这么别扭,原来这个编辑控件对chrome支持的不好,用IE重新发一个:public class Compare {
    // 使用boolean表示符号位,true为正,false为负
    private static final boolean signToBool[] = { true, false }; // 取得整数的符号位
    private static final boolean getSignOfInteger(int integer) {
    return signToBool[integer >>> 31];
    } // 比较int1和int2大小,int1>=int2返回true,否则返回false
    public static boolean compareInteger(int int1, int int2) {
    boolean signOfInt1 = getSignOfInteger(int1);
    boolean signOfInt2 = getSignOfInteger(int2);
    boolean signInt1MinusInt2 = getSignOfInteger(int1 - int2);
    // 原理很简单:符号相同返回int1-int2的符号位(为正表示int1>=int2);不同返回int1的符号位
    return (!(signOfInt1 ^ signOfInt2) && signInt1MinusInt2)
    || ((signOfInt1 ^ signOfInt2) && signOfInt1);
    } public static int maxInteger(int int1, int int2) {
    return compareInteger(int1, int2) ? int1 : int2;
    }
    }用符号位实现的
      

  10.   

    呵呵,再加一个 // 比较int1和int2大小:大返回1,等返回0,小返回-1
    public static int compareIntegerC(int int1, int int2) {
    int signbitOfInt1 = int1 >>> 31;
    int singbitOfInt2 = int2 >>> 31;
    int signbitOfInt1MinusInt2 = (int1 - int2) >>> 31;
    int signbitOfInt2MinusInt1 = (int2 - int1) >>> 31;
    return singbitOfInt2 - signbitOfInt1
    + ((1 - singbitOfInt2 + signbitOfInt1) & 1)
    * (signbitOfInt2MinusInt1 - signbitOfInt1MinusInt2);
    }
      

  11.   

    你这个int1-int2要是越界了,结果还对吗?
      

  12.   

    GOOD  !    study !
      

  13.   

    int
     可有赋值那么大吗?
      

  14.   

    已经做了越界的判断(符号位相同的操作是不会越界的,越界主要是符号为不同的操作),做过3组测试(简单的比较、边界测试和10000组随机数的测试)都pass
      

  15.   

    强烈支持!就是因为这样,所以中国人的技术只能靠外国的技术做支撑,比如只会用用微大函数库,那有没有想过要自己去做个函数库呢,再说大点就是有没有想过我们国家怎么就没有人去开发.NET呢,就是因为只想用用人家的技术做现成的开发,也导致于说现在的IT业会被淘汰。
    本人虽然没什么技术,现在做这个小项目都做不好。
    但我只想通过这道面试题表达出自己的想法
      

  16.   

    public class Test2
    {
    public static void main(String args[])
    {
    int a=1;
    int b=2;
    System.out.println(compareNumbers(3,33));
    }
    public static String compareNumbers(int a,int b)
    {
    String s1=String.valueOf(a);
    String s2=String.valueOf(b);
    int result=0;
    String s=null;
    //如果两个符号相同
    if(!(s1.contains("-")^s2.contains("-")))
    {
    result=a-b;
    if(String.valueOf(result).contains("-"))
    {
    s=a+"<"+b;
    }
    else if(String.valueOf(result).startsWith("0"))
    {
    s=a+"="+b;
    }
    else
    {
    s=a+">"+b;
    }
    }
    else
    {
    if(s1.contains("-"))
    {
    s=a+"<"+b;
    }
    else
    {
    s=a+">"+b;
    }
    }
    return s;
    }
    }
    可能不怎么好,硬凑的,也算解决问题了
      

  17.   

    很不错嘛
    四川 锦年科技 监控软件 www.jyear.cn
      

  18.   

    看到这个话题,觉得很有意思。a、b两数正负符号出现情况,只可能是四种情形。
    问题分情况讨论后,可以转化为更容易解决的子问题
    我们知道,比较两个“非负整数”是容易的。构思下面这个函数
      // 如果a>=b返回true,否则返回false
      public boolean ge(int a, int b) {
        int pos1 = (new int[][] { {
                    0, 1}
                    , {
                    2, 3}
        }
            )[a >>> 31][b >>> 31];
        int m = (new int[] {
                 1, 0, 0, 0})[pos1] * a + (new int[] {
                                           0, -1, 0, -1})[pos1] * b;
        int n = (new int[] {
                 0, 0, -1, -1})[pos1] * a + (new int[] {
                                             1, 0, 0, 0})[pos1] * b;
        return (new boolean[] {true, false})[ (m - n) >>> 31];
      }
      

  19.   


    public class TestGe {  public boolean ge(int a, int b) {
        int pos1 = (new int[][] { {
                    0, 1}
                    , {
                    2, 3}
        }
            )[a >>> 31][b >>> 31];
        int m = (new int[] {
                 1, 0, 0, 0})[pos1] * a + (new int[] {
                                           0, -1, 0, -1})[pos1] * b;
        int n = (new int[] {
                 0, 0, -1, -1})[pos1] * a + (new int[] {
                                             1, 0, 0, 0})[pos1] * b;
        return (new boolean[] {true, false})[ (m - n) >>> 31];
      }  public TestGe() {
        int a, b;
        a = 100;
        b = 99;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = 99;
        b = 100;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = 99;
        b = 99;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = 100;
        b = -99;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = 99;
        b = -100;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = 99;
        b = -99;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = -100;
        b = 99;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = -99;
        b = 100;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = -99;
        b = 99;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = -100;
        b = -99;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = -99;
        b = -100;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = -99;
        b = -99;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = -2147483648;
        b = 2147483647;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = 2147483647;
        b = -2147483648;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = 2147483647;
        b = 2147483646;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
        a = -2147483648;
        b = -2147483647;
        System.out.println("a=" + a + "\t b=" + b + "\t ge(a,b)=" + ge(a, b));
      }  public static void main(String[] args) {
        new TestGe();
      }
    }
      

  20.   

    public class Bigger {
        public static void main(String args[]){
            int a = -2147483648;
            int b = 2147483647;
            
            String[] strArray = {"a>=b", "a<b"};
                    
            int i = (int)((long)a-(long)b >>> 63);
            
            System.out.println(strArray[i]);
        }
    }
    不过听人说减法操作其实就是移位操作