定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句

来源:互联网 发布:淘宝网账户注册流程 编辑:程序博客网 时间:2024/06/10 01:35

网上有较多的帖子讨论一些面试的题目,其中有一道就是“定义一个宏,比较两个数a、b的大小,不能使用大于、小于、if语句”

从原理上将,一个int整形变量,最高位是正负位,只要知道两者差值最高位是正还是负,差是零还是非零就能知道两个数的大小。


这里简单整理了网络上给出的较多答案,并做了简单的验证。


验证一:

#define ZHENG(i) ((i >> 31) == 0)#define FU(i) ((i >> 31) != 0)#define COMPARE_1(a, b) ((ZHENG(a) && FU(b)) \                  || (((ZHENG(a) && ZHENG(b)) \  || (FU(a) && FU(b))) \  && ((((a) - (b)) >> 31) == 0)))

验证二:

#define COMPARE_2(a, b) (((((long)((b)-(a)))&0x80000000)?-1:0)|((((long)((a)-(b)))&0x80000000)?1:0))

验证三:

#define COMPARE_3(a, b) ( ( ( (int)( b ) )-( (int)( a ) ) ) >> ( sizeof( int )*8-1 ) & 0x1 )

验证四:

#define COMPARE_4(a, b) (((b) - (a) & (0x1 << 31)) >> 31) 

验证五:

#define MAX(a, b) (((a)-(b)) & 0x80000000 ) ? (b) : (a)

验证六:

#define new_big_than(a, b) !!( ((a) < 0 || (b) < 0) ? (((b) - (a) & (0x1 << 31)) >> 31) : (( (b) == 0)? (a): (a)/(b)) )

验证七:

#define old_big_than(a, b) !!(((b) - (a) & (0x1 << 31)) >> 31)

验证八:

#define big_than(a, b) (b - a)?(((unsigned long)(((b) - (a)) / abs((b) - (a))) & (0x1  << 31)) >>  31):0

只要根据上面的原理,就能分析出这个宏究竟该如何写。这里先给出验证的结果:



验证代码:

#include <stdio.h>#define ZHENG(i) ((i >> 31) == 0)#define FU(i) ((i >> 31) != 0)#define COMPARE_1(a, b) ((ZHENG(a) && FU(b)) \                  || (((ZHENG(a) && ZHENG(b)) \  || (FU(a) && FU(b))) \  && ((((a) - (b)) >> 31) == 0)))#define COMPARE_2(a, b) (((((long)((b)-(a)))&0x80000000)?-1:0)|((((long)((a)-(b)))&0x80000000)?1:0))#define COMPARE_3(a, b) ( ( ( (int)( b ) )-( (int)( a ) ) ) >> ( sizeof( int )*8-1 ) & 0x1 )#define COMPARE_4(a, b) (((b) - (a) & (0x1 << 31)) >> 31) #define MAX(a, b) (((a)-(b)) & 0x80000000 ) ? (b) : (a)#define new_big_than(a, b) !!( ((a) < 0 || (b) < 0) ? (((b) - (a) & (0x1 << 31)) >> 31) : (( (b) == 0)? (a): (a)/(b)) )#define old_big_than(a, b) !!(((b) - (a) & (0x1 << 31)) >> 31)#define big_than(a, b) (b - a)?(((unsigned long)(((b) - (a)) / abs((b) - (a))) & (0x1  << 31)) >>  31):0int main(int argc, char **argv){int  iInput = 1;char buffer1[64];char buffer2[64];int  iVal1, iVal2;    while(iInput){printf("Please input your first and second value: (\"exit\" to quit the program)\r\n");scanf("%s", buffer1);if (0 == strcmp("exit", buffer1)){iInput = 0;break;}scanf("%s", buffer2);if (0 == strcmp("exit", buffer2)){iInput = 0;break;}iVal1 = atoi(buffer1);iVal2 = atoi(buffer2);printf("==============================\r\n");printf("%d > %d? test result:\r\n", iVal1, iVal2);printf("COMPARE_1(%d, %d) = %d\r\n", iVal1, iVal2, COMPARE_1(iVal1, iVal2));printf("COMPARE_2(%d, %d) = %d\r\n", iVal1, iVal2, COMPARE_2(iVal1, iVal2));printf("COMPARE_3(%d, %d) = %d\r\n", iVal1, iVal2, COMPARE_3(iVal1, iVal2));printf("COMPARE_4(%d, %d) = %d\r\n", iVal1, iVal2, COMPARE_4(iVal1, iVal2));printf("MAX(%d, %d) = %d\r\n", iVal1, iVal2, MAX(iVal1, iVal2));printf("big_than(%d, %d) = %d\r\n", iVal1, iVal2, big_than(iVal1, iVal2));printf("old_big_than(%d, %d) = %d\r\n", iVal1, iVal2, old_big_than(iVal1, iVal2));printf("new_big_than(%d, %d) = %d\r\n", iVal1, iVal2, new_big_than(iVal1, iVal2));printf("++++++++++++++++++++++++++++++\r\n");printf("%d > %d? test result:\r\n", iVal2, iVal1);printf("COMPARE_1(%d, %d) = %d\r\n", iVal2, iVal1, COMPARE_1(iVal2, iVal1));printf("COMPARE_2(%d, %d) = %d\r\n", iVal2, iVal1, COMPARE_2(iVal2, iVal1));printf("COMPARE_3(%d, %d) = %d\r\n", iVal2, iVal1, COMPARE_3(iVal2, iVal1));printf("COMPARE_4(%d, %d) = %d\r\n", iVal2, iVal1, COMPARE_4(iVal2, iVal1));printf("MAX(%d, %d) = %d\r\n", iVal2, iVal1, MAX(iVal2, iVal1));printf("big_than(%d, %d) = %d\r\n", iVal2, iVal1, big_than(iVal2, iVal1));printf("old_big_than(%d, %d) = %d\r\n", iVal2, iVal1, old_big_than(iVal2, iVal1));printf("new_big_than(%d, %d) = %d\r\n", iVal2, iVal1, new_big_than(iVal2, iVal1));printf("==============================\r\n");}    printf("Exit!\r\n");    return 0;}



原创粉丝点击