利用位运算计算某种数据类型的最大值和最小值

  1. 常见数值的补码

     数值
    补码
     0
    0000 0000
     1
    0000 0001
       -1
    1111 1111
    -256
    1000 0000
      255
    0111 1111








    最高位是符号位,0表示正数,1表示负数。

  2. 已知负数求补码
    方法:将对应绝对值的补码按位取反,然后加上1,比如求-1的补码,先取1的补码:
     0000 00011
    按位取反1111 1110 
    加上11111 1111-1
  3. 已知负数的补码,求负数
    方法:补码-1,然后按位取反得到绝对值,然后加上负号
     1111 1111 
    减去11111 1110 
    按位取反0000 00011
    加上负号 -1
    也可以直接按位取反,得到绝对值加上1,然后加上负号
     1111 1111 
    按位取反0000 00000
    加上1 1
    填上负号 -1
    再如:
     1000 0000 
    按位取反0111 1111127
    加上1 128
    填上负号 -128
  4. 最大值和最小值的特征
    2550111 1111
    -2561000 0000
    327680111 1111 1111 1111
    -327691000 0000 0000 0000
    从以上补码,可以看出,任何一种数据类型,其最大值的特点是最高位为0,其余为均为1,而最小值,其特点是最高位为1,其余位均为0。因此对于任何一种数据类型,只要通过位移运算,得到符合上述特点的补码就可以获取到相应数据类型的最大值和最小值。现假设要计算短整型的数据范围,则其最大值和最小值的补码如下:
    最大值0111 1111 1111 1111
    最小值1000 0000 0000 0000
    要获得以上补码,我们可以看到,最简单的是获得最小值的补码,它可以通过对1左移15位获得,而如果获得了最小值的补码,那么按位取反,就可以获得最大值的补码,过程如下:
     0000 0000 0000 0001  
    左移15位1000 0000 0000 0000-32769
    按位取反0111 1111 1111 111132768

    下面是实验:
    1<<(sizeof(int)*8-1)
    -2147483648
    ~(1<<(sizeof(int)*8-1))
    2147483647
    
    注意以下差异:
    (short)(1<<(sizeof(short)*8-1))
    -32768
    (short)(~(1<<(sizeof(short)*8-1)))
    32767
    ((short)1)<<(sizeof(short)*8-1)
    32768
    ~(((short)1)<<(sizeof(short)*8-1))
    -32769
    
    ((int)1)<<(sizeof(int)*8-1)
    -2147483648
    ~(((int)1)<<(sizeof(int)*8-1))
    2147483647
    
    ((long)1)<<(sizeof(long)*8-1)
    -2147483648
    ~(((long)1)<<(sizeof(long)*8-1))
    2147483647

    于是,对于一个对输入的整形数乘以一定倍数的模板函数,可以通过下面的方式确定数值范围:
    template<typename T>
    int Test(T x,int nScale)
    {
    	T nMin = (T)(1<<(sizeof(x)*8-1));		//确定该类型的最大值
    	T nMax = (T)(~(1<<(sizeof(x)*8-1)));		//确定该类型的最小值
    	int nVal = x*nScale;			//乘以一定的倍数
    	if(nVal<nMin) return nMin;		//如果越下界,则返回下界值
    	else if(nVal>nMax) return nMax;		//如果越上界,则返回上界值
    	else return nVal;			//没有越界,返回乘倍后的值
    }


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

深蓝静音

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

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

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

打赏作者

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

抵扣说明:

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

余额充值