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

网上有较多的帖子讨论一些面试的题目,其中有一道就是“定义一个宏,比较两个数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):0

int 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;
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值