返回两个整数的最大值,不使用比较运算符和if,while,switch,for,?:,以及任何比较语句

方法一:首先我们来看看用函数怎么样实现这个题目?

#include <iostream>

using namespace std;

int MAX(int a,int b)
{
    int d=a-b;
    int flag=((unsigned int)d)>>31;
   //此处将d转化为 unsigned int的目的是,相右移动时,低位移出,高位补零,无无符号数没有符号位的
  //概念,所以只能补0.而有符号数,比如-7,它的符号位就是1
    int array[]={a,b};
    return array[flag];
}

int main()
{
    
    cout<<MAX(1,2)<<endl;
    cout<<MAX(5,2)<<endl;
    cout<<MAX(3,100)<<endl;
	
	return 0;
}

方法二:利用宏来实现,在GCC编译器下来实现

//将刚刚实现的程序进行优化一下
#include <iostream>

using namespace std;

int MAX(int a,int b)
{
    int array[]={a,b};
    return array[((unsigned int)(a-b))>>31];
}

int main()
{
    
    cout<<MAX(1,2)<<endl;
    cout<<MAX(5,2)<<endl;
    cout<<MAX(3,100)<<endl;
	
	return 0;
}

然后再将上面的程序写成宏的形式
在GCC编译器下,利用2个参数实现如下:
#include <iostream>

using namespace std;

#define MAX(a,b) ({int array[]={a,b};array[((unsigned int)(a-b))>>31];})

int main()
{
    
    cout<<MAX(1,2)<<endl;
    cout<<MAX(5,2)<<endl;
    cout<<MAX(3,100)<<endl;
	
	return 0;
}

注意:({})这样的语法是GCC编译器下特有的语法,与标准C/C++编译器下 ()是一样的,与逗号表达式类似。

比如:

标准C/C++编译器下的实现

int a=1;

int  b=2;

int r=(a=1,b=2,a+b); // r=3

//GCC编译器的实现

int r=({int a=1;int b=2;a+b;});

 

#include <iostream>

using namespace std;

#define MAX(a,b,type) ({type array[]={a,b};array[((unsigned int)(a-b))>>31];})

int main()
{
    float a=7.8;
    float b=10.34;
    
    cout<<MAX(a,b,float)<<endl;
    //cout<<MAX(5,2,int)<<endl;
    //cout<<MAX(3.22,100.12,double)<<endl;
	
	return 0;
}

//将上述程序优化一下,可以支持任意的类型,不仅仅是int类型,也可以是其他的类型,比如float,double等。

 

 

进一步的深度思考有没有考虑过,a-b会发生溢出的现象呢?就比如下面的程序:

#include <iostream>

using namespace std;

#include <iostream>

using namespace std;

int MAX(int a,int b)
{
    int d=a-b;
    cout<<"d="<<d<<endl;//因为会发生溢出,所以此时 d=2147483647 
    int flag=((unsigned int)d)>>31;
    int array[]={a,b};
    return array[flag];
}

int main()
{
    
    int a=-2;
    int b=2147483647;//此时b表示的4字节有符号整数的最大值,2^31-1
    
    cout<<MAX(a,b)<<endl;
	
	return 0;
}

这个时候那么这个比较算法是不是出现问题呢?对,因为没有考虑到溢出的情况在里面。

#include <stdio.h>


int MAX(int a,int b)
{
    //用来保存原始数据中的两个数
    int array[]={a,b};
    //用来保存两个数中的最大值,根据a,b的正负组合,一共有4种情况
    int r[]=
    {
        array[((unsigned int)(a-b))>>31],//a,b都是正数的情况
        //如果a<b,最高位一定为1,存入b ;如果a>b,最高位一定为0,存入a
        a,//a正b负,a一定大于b
        b,//a负b正,b一定大于a
        array[((unsigned int)(a-b)>>31)] //a,b都是负数的情况
        //如果a<b ,这最高位一定为1,存入b; 如果a>b,最高位一定为0,存入a
    };

    //判读a和b的正负组合属于那种情况
    //int转化为unsigned int后,最高位就有2种情况,正数或者0:0,负数:1
    //组合;同正 00,正负01,负正10,负负11,恰好是array的下标
    unsigned x=(((unsigned int)(a))>>30)&2; //取a的最高位,作为下标右边的第2位
    unsigned y=((unsigned int)(b))>>31;    //取b的最高位,作为下标右边第1位
    unsigned i=x|y; //合成a和b的最高位作为array的下标
    return r[i];//取到相应情况的最大值

}



int main()
{

    int a=-2;
    int b=2147483647;//此时b表示的4字节有符号整数的最大值,2^31-1

    printf("%d\n",MAX(a,b));

    return 0;
}

与之相对应的宏为下面所示:这个宏可以适用于任何类型

#define MAX(a, b, type) ({type _ab_[] = {(a), (b)}; int _i_ = ((unsigned long long)((a)-(b))) >> 63; type _r_[] = {_ab_[_i_], (a), (b), _ab_[_i_]}; _r_[((((unsigned long long)(a)) >> 62)&2)|(((unsigned long long)(b)) >> 63)];})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

repinkply

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值