C++右移运算符的一个小坑及解决

 更新时间:2025年09月10日 08:40:32   作者:玄黄问道  
文章指出右移运算符处理负数时左侧补1导致死循环,与除法行为不同,强调需注意补码机制以正确统计二进制1的个数

我遇到了这么一个函数

template<typename T>
unsigned char countByt(T byt)
{
    unsigned char num=0;
    while(byt)
    {
        num += (byt & 0x01);
        byt >>= 1;
        // cout<<hex<<byt<<endl;
    }
    return num;
}

很明显,这个函数是统计byt二进制下1的个数。

没毛病

但当我输入负数的时候,就会陷入死循环。

用那行注释中的东西输出中间过程:

由此可以看到

  • 非负数下,右移运算符,左面补0.
  • 负数下,右移运算符,左面补1.

我对代码进行如下修改:

template<typename T>
unsigned char countByt(T byt)
{
    unsigned char num=0;
    while(byt)
    {
        num += (byt & 0x01);
        byt/=2;
        //byt >>= 1;
        //cout<<hex<<byt<<endl;
    }
    return num;
}

负数的结果:

这个时候,统计的是其所对应正数的1的个数。

也很好理解

补码是其正数按位取反再加1

可以看到,一个数的正和负,它们最后一位一定是一样的!

1、如果我们用/=2来的话:

-1/2=0

那结果跟正数统计是一样的。

2、如果我们用>>=1的话:

-1:ffffffff

右移一位后,由于左侧补1,

还是:ffffffff

死循环就发生了。

但我在实验的时候又发现了有趣的一点:

    int n;
    while(cin>>n)
    {
        cout<<(n>>1)<<endl;

    }
1
0
-1
-1

2
1
-2
-1


3
1
-3
-2


9
4
-9
-5


8
4
-8
-4

可以看到:>>=1 等价于除以2后的(向下)取整。

而 / 运算符,是先对正数部分取整,再加符号。

因此对两个int变量a,b:

a/b不一定小于 等于(double)a/b;

    
    while(cin>>a>>b)
        cout<<((a/b)<=((double)a/b))<<endl;
        

输出:

5 3
1
-5 3
0
-5 -3
1
5 -3
0

总结

当使用右移运算符的时候,一定要注意输入为负数的可能!在负数下 >>1 和 /=2 并不等价!

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 使用Qt开发实现字幕滚动效果

    使用Qt开发实现字幕滚动效果

    我们经常能够在外面看到那种滚动字幕,那么就拿qt来做一个吧,文章通过代码示例给大家介绍的非常详细,对大家的学习或工作有有一定的参考价值,需要的朋友可以参考下
    2023-11-11
  • 使用Matlab制作大富翁小游戏的过程详解

    使用Matlab制作大富翁小游戏的过程详解

    大富翁大家都玩过,走到建筑的位置可以买地,第二圈走到买过的地可以升级,别人经过后需要付过路费,每次经过起点都会获得一定资金,玩到最后还没破产的就是胜者,本文将制作一个Matlab版的大富翁小游戏,需要的可以参考一下
    2022-02-02
  • C++中函数重载与引用的操作方法

    C++中函数重载与引用的操作方法

    C++中函数重载允许同名函数根据参数列表的不同而执行不同的功能,这依赖于名字修饰或名字改编(Name Mangling)机制,而引用则是为变量创建一个别名,不会开辟新的内存空间,本文介绍了C++中函数重载与引用的操作,感兴趣的朋友一起看看吧
    2024-10-10
  • 基于c中使用ftruncate()前需要fflush(),使用后需要rewind()的深入探讨

    基于c中使用ftruncate()前需要fflush(),使用后需要rewind()的深入探讨

    本篇文章是对在c中使用ftruncate()前需要fflush(),使用后需要rewind()进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C语言实现简单的飞机大战游戏

    C语言实现简单的飞机大战游戏

    这篇文章主要为大家详细介绍了C语言实现简单的飞机大战游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • 纯C语言:分治快速排序源码分享

    纯C语言:分治快速排序源码分享

    这篇文章主要介绍了分治快速排序源码,有需要的朋友可以参考一下
    2014-01-01
  • Vc++ 控件List Control用法总结

    Vc++ 控件List Control用法总结

    这篇文章主要介绍了Vc++ 控件List Control用法总结的相关资料,需要的朋友可以参考下
    2015-06-06
  • C语言数据结构之顺序数组的实现

    C语言数据结构之顺序数组的实现

    这篇文章主要介绍了C语言数据结构之顺序数组的实现的相关资料,这里提供实现实例,希望通过本文能帮助到大家,需要的朋友可以参考下
    2017-08-08
  • C++实现判断一个字符串是否为UTF8或GBK格式的方法

    C++实现判断一个字符串是否为UTF8或GBK格式的方法

    这篇文章主要介绍了C++实现判断一个字符串是否为UTF8或GBK格式的方法,涉及C++针对字符编码的遍历、判断、编码转换等相关操作技巧,需要的朋友可以参考下
    2017-11-11
  • C++结构体数组实现贪吃蛇

    C++结构体数组实现贪吃蛇

    这篇文章主要为大家详细介绍了C++结构体数组实现贪吃蛇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03

最新评论