LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3049|回复: 37

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

[复制链接]
发表于 2006-9-8 11:21:31 | 显示全部楼层 |阅读模式
CSDN上炒得火热(汗)的一道老面试题,不过我看又对又好的答案还没出现。。。

[color="Red"]编写一个函数比较两个整数大小,但不能使用任何比较操作符
发表于 2006-9-8 11:32:18 | 显示全部楼层
好玩,我试一下:
  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.         return (var1 - var2);
  8. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-9-8 11:37:49 | 显示全部楼层
Post by 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.         return (var1 - var2);
  8. }
复制代码


有没有考虑溢出情况?
var1 = -268435441
var2 = 2147483647
回复 支持 反对

使用道具 举报

发表于 2006-9-8 11:59:01 | 显示全部楼层
呦,该打!
太晚了,我先睡觉,明天再想。。。;-)
回复 支持 反对

使用道具 举报

发表于 2006-9-8 12:30:42 | 显示全部楼层
就算正确返回我还是得用比较符判断是否大于小于等于0啊
回复 支持 反对

使用道具 举报

发表于 2006-9-8 12:59:54 | 显示全部楼层
不知道 "不能使用任何比较操作符" 的概念有多大, 暂时理解为不使用 >, <, ==, !=
下面是判断大于的函数, 类似的可写出其它几种操作
[PHP]
#include <stdio.h>

/* return 1 if a > b */
int greater(int a, int b)
{
        int sa = a >> 31; /* sign of a */
        int sb = b >> 31; /* sign of b */
        if (!sa && sb) return 1; /* a >= 0 && b < 0 */
        if (sa && !sb) return 0; /* a < 0 && b >= 0 */

        int c = a - b;
        if (!c) return 0; /* a == b */

        int sc = c >> 31; /* sign of (a - b) */
        return !sc;
}
int main(void)
{
#define N 13
        int nums[N][2] = {
                {1, 1},
                {1, 0},
                {1, -1},
                {0, 1},
                {0, 0},
                {0, -1},
                {-1, 1},
                {-1, 0},
                {-1, -1},
                {1, 2},
                {2, 1},
                {-1, -2},
                {-2, -1}
        };
        int i;
        for (i = 0; i < N; i++) {
                int a = nums[0];
                int b = nums[1];
                printf("%2d > %2d: %d\n", a, b, greater(a, b));
        }
        return 0;
}
[/PHP]
回复 支持 反对

使用道具 举报

发表于 2006-9-8 13:14:01 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main(int argc,char *argv[])
  4. {
  5.         int num1,num2;
  6.         if(argc != 3)
  7.         {
  8.                 printf("Usage: cmp_int num1 num2\n");
  9.                 exit(1);
  10.         }
  11.         num1 = atoi(argv[1]);
  12.         num2 = atoi(argv[2]);
  13.         num1 -= num2;
  14.         if(num1 >> 31)
  15.                 printf("The first number is less than the second one\n");
  16.         else if(num1)
  17.                 printf("The first number is greater than the second one\n");
  18.         else
  19.                 printf("The two numbers are equal\n");
  20.         return 0;
  21. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-9-8 16:27:07 | 显示全部楼层
提取符号位,如果异号,显然知道谁大谁小;然后在两者同号的情况下,取其差值的符号位来判断谁大谁小。也许可以避开溢出的问题。
  1. #include <stdio.h>
  2. int cmp( int a, int b )
  3. /* return value 1: means a > b;
  4. *                    0: means a = b;
  5. *                   -1: means a < b;
  6. */
  7. {
  8.   const int s = sizeof( int ) * 8 - 1;
  9.   int sa = a >> s;
  10.   int sb = b >> s;
  11.   if (sa)
  12.   {
  13.       if (!sb)
  14.         return -1;
  15.   }
  16.   else if (sb)
  17.   {
  18.       return 1;
  19.   }
  20.   if ( (b-a) >> s )
  21.     return 1;
  22.   else if ( (a-b) >> s )
  23.     return -1;
  24.   else
  25.     return 0;
  26. }
  27. int main()
  28. {
  29.   int a, b;
  30.   scanf("%d %d", &a, &b);
  31.   switch ( cmp( a, b ) )
  32.   {
  33.   case 1:
  34.     printf( "%d > %d\n", a, b );
  35.     break;
  36.   case 0:
  37.     printf( "%d = %d\n", a, b );
  38.     break;
  39.   case -1:
  40.     printf( "%d < %d\n", a, b );
  41.     break;
  42.   default:
  43.     break;
  44.   }
  45.   return 0;
  46. }
复制代码

参考:高等教育自学考试计算机原理冲刺模拟试卷
……
47.在计算机中,由于机器码的位数通常是给定的,因此计算机中数的表示范围(允许取值范围)是有限的。若两数进行加减运算的结果超出给定的取值范围就称为溢出。当计算过程中出现溢出时,必须及时处理。定点机如出现溢出,则要停止运算,进行中断处理。为了判断“溢出”是否发生,可采用两种检测方法:
……
(2)单符号位操作检测方法。这种判断溢出的方法是当操作数中的加数与被加数符号相同时,若运算结果的符号与操作数的符号不一致,则表示溢出;否则,表示没有溢出。而当加数和被加数符号不同时,相加运算的结果是绝对不会溢出的。
……

http://www.sooxue.com/kspx/zxks/zlst/200511/18196_9.html

P.S.
才发现跟DoDo学长的方法一样,但我采用strcmp的接口模式。接口不同而已。

根据楼下biinn的思路进行了修改。
  1. #include <stdio.h>
  2. int cmp( int a, int b )
  3. /* return value 1: means a > b;
  4. *              0: means a = b;
  5. *             -1: means a < b.
  6. */
  7. {
  8.     const int bit_width = ( sizeof( int ) << 3 ) - 1;
  9.     int rslt = ( a >> bit_width ) - ( b >> bit_width );
  10.     if ( !rslt )
  11.     {
  12.         rslt = (( a - b ) >> bit_width ) - (( b - a ) >> bit_width );
  13.     }
  14.     return rslt;
  15. }
  16. int main()
  17. {
  18.     int a, b;
  19.     while (1)
  20.     {
  21.         scanf( "%d %d", &a, &b );
  22.         switch ( cmp( a, b ) )
  23.         {
  24.         case 1:
  25.             printf( "%d > %d\n", a, b );
  26.             break;
  27.         case 0:
  28.             printf( "%d = %d\n", a, b );
  29.             break;
  30.         case - 1:
  31.             printf( "%d < %d\n", a, b );
  32.             break;
  33.         default:
  34.             break;
  35.         }
  36.     }
  37.     return 0;
  38. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-9-8 21:56:48 | 显示全部楼层
Post by Lolita
有没有考虑溢出情况?
var1 = -268435441
var2 = 2147483647
Please check this version:
  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 = var2 >> (bit_width -1) -
  10.           var1 >> (bit_width -1);
  11.     if (msb)
  12.         rtnvar = msb;
  13.     else
  14.         rtnvar = var1 - var2;
  15.     return rtnvar;
  16. }
复制代码
回复 支持 反对

使用道具 举报

发表于 2006-9-8 22:01:06 | 显示全部楼层
to MatthewGong 兄:
从你的资料来看, 应该称呼我为学弟才对
回复 支持 反对

使用道具 举报

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

本版积分规则

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