LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
楼主: soloforce

一道面试题:编写一个函数比较两个整数大小,但不能使用任何比较操作符

[复制链接]
发表于 2006-9-9 10:28:45 | 显示全部楼层
Post by MatthewGong

P.S.
我这边gcc4.1下, -1234 >> 31 的结果是-1而不是1…… C标准怎么说的呀?我都忘了。

biinn,这样的话
    msb = var2 >> (bit_width -1) - var1 >> (bit_width -1);
是不是应该改为:
   msb = var1 >> (bit_width -1) - var2 >> (bit_width -1);

多谢,Matthew 兄。看来光拍脑袋是不行的啊。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-9-9 10:46:00 | 显示全部楼层
大家写得都比我好,我原来的代码居然用了循环,而且没用上减法。。。
  1. const int BYTE_BITS=8;
  2. const int EQUAL=0;
  3. const int MORE=1;
  4. const int LESS=-1;
  5. int cmp(int a, int b)
  6. {
  7.     int mask=0x1;
  8.     mask<<=BYTE_BITS*sizeof(int)-1;
  9.    
  10.     // equal
  11.     if(!(a^b))return EQUAL;  
  12.     // one is positive , while the other is negative
  13.     if( (a&mask)^(b&mask) ) return (a&mask) ? LESS : MORE ;
  14.        
  15.     // check the rest bits
  16.     while( !((a&mask)^(b&mask)) ) mask>>=1;
  17.     return (a&mask) ? MORE : LESS ;
  18. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-9-9 11:13:47 | 显示全部楼层
Post by Lolita
大家写得都比我好,我原来的代码居然用了循环,而且没用上减法。。。

今天问了我的同事这个问题,她的思路和罗版主的类似。
回复 支持 反对

使用道具 举报

发表于 2006-9-9 11:18:59 | 显示全部楼层
Post by Arthur.Echo

  1.         i = (((num1 - num2) >> 31) * 2) + ((num2 - num1) >> 31);
复制代码

愚钝,看不懂 Arthur 兄的思路。只好用罗版主的数字跑了一下:
num1 = -268435441
num2 = 2147483647
结果 i = -1, result[1]:num1 > num2 ?
回复 支持 反对

使用道具 举报

发表于 2006-9-9 11:19:18 | 显示全部楼层
Post by Lolita


  1.     // one is positive , while the other is negative
  2.     if( (a&mask)^(b&mask) ) return (a&mask) ? LESS : MORE ;
复制代码

昨天晚上想用“异或”的, 愣是没想起来操作符号是什么。

lolita的位操作******************!承教。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-9-9 11:33:46 | 显示全部楼层
Post by biinn
愚钝,看不懂 Arthur 兄的思路。只好用罗版主的数字跑了一下:
num1 = -268435441
num2 = 2147483647
结果 i = -1, result[1]:num1 > num2 ?


貌似也是溢出了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-9-9 11:45:26 | 显示全部楼层
总结一下:
1、不要盲目用减法,因为异号整数相减容易溢出; 确保两数是同号后则可以用减法。
2、负整数右移 ( sizeof(int)*8-1 ) 后,得到的是 -1 而不是 1, 因为负整数右移是算术右移SAR。
3、注意移位运算的优先级比加减法低。
4、不要直接用31, 因为有些系统的int不是32位的。
5、 楼下补充:)

biinn兄的这个解比较好
  1. int comp_int(int var1, int var2)
  2. /* return value < 0: means var1 < var2;
  3. *              = 0: means var1 = var2;
  4. *              > 0: means var1 > var2;
  5. */
  6. {
  7.     int bit_width, msb, rtnvar;
  8.     bit_width = sizeof(int) << 3;   
  9.     msb =( var1 >> (bit_width -1) ) - ( var2 >> (bit_width -1) ) ;
  10.     if (msb)
  11.         rtnvar = msb;
  12.     else
  13.         rtnvar = var1 - var2;
  14.     return rtnvar;
  15. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-9-9 12:14:34 | 显示全部楼层
Post by biinn
愚钝,看不懂 Arthur 兄的思路。只好用罗版主的数字跑了一下:
num1 = -268435441
num2 = 2147483647
结果 i = -1, result[1]:num1 > num2 ?

就是没有考虑溢出的问题,再想想
回复 支持 反对

使用道具 举报

发表于 2006-9-9 12:28:19 | 显示全部楼层
Post by Lolita
总结一下:
1、不要盲目用减法,因为异号整数相减容易溢出; 确保两数是同号后则可以用减法。
2、负整数右移 ( sizeof(int)*8-1 ) 后,得到的是 -1 而不是 1, 因为负整数右移是算术右移SAR。
3、注意移位运算的优先级比加减法低。

这三点就是我从这道题中学到的东西,谢谢大家。
回复 支持 反对

使用道具 举报

发表于 2006-9-9 14:27:17 | 显示全部楼层
拜各位了,看都看了半天……思路是在叫绝
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表