• C++跳坑记:位移超出范围的处理


    在C++编程中,数据类型的选择不仅影响内存占用和性能,还可以对某些操作的结果产生意想不到的影响。今天,我将分享一个关于C++在不同变量类型下位移操作结果的发现。

    位移操作是C++中常见的对整数的高效操作之一。然而,我们可能会忽视一个细节:不同的编译器和数据类型可能会导致位移操作的结果不同。

    示例代码

    让我们看一个简单的计算512右移n位的代码,来展示这个问题:

    #include 
    using namespace std;
    
    int main() {
        int L = 512;
        for (int i = 0; i < 64; i++) {
            cout << L << " >> " << i << " = " << (L >> i) << endl;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在上述代码中,我们使用了一个整数 L,并尝试对其进行右移操作,观察结果:
    512>>0 = 512
    512>>1 = 256
    512>>2 = 128
    512>>3 = 64
    512>>4 = 32
    512>>5 = 16
    512>>6 = 8
    ……
    512>>30 = 0
    512>>31 = 0
    512>>32 = 512
    512>>33 = 256
    512>>34 = 128
    ……

    发现

    我天真地以为,只要右移的位数超出范围,结果为0。
    但实际结果让我出乎意料:当 i 的值达到 32 时,512 >> 32 的结果变成了 512,然后往后,512 >> 33 等于 256,512 >> 34 等于 128,如此类推。
    这与Python的计算表现完全不同。Python的运算结果是,只要超出范围,结果永远为零。
    这意味着,当 i 大于等于 32 时,C / C++的右移操作不再产生预期的结果,而是保持原始值,这将严重影响后续的运算结果。

    解决方案

    为了解决这个问题,我们尝试将 L 的数据类型更改为 long,但很遗憾结果与使用 int 类型的情况一样,仍然无法得到正确的结果。
    最后,我将 L 的类型更改为 long long,才得出了预期的结果。

    #include 
    using namespace std;
    
    int main() {
    	// 把L的类型由int改为long long
        long long L = 512;
        for (int i = 0; i < 64; i++) {
            cout << L << " >> " << i << " = " << (L >> i) << endl;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    运行结果截图

    在这里插入图片描述

    2023年10月5日更新

    解决方法二:使用std::bitset
    std::bitset<32> 是C++标准库中的一个固定大小的数据类型,它包含了32个二进制位,无法动态调整大小。这意味着无论如何,std::bitset<32> 都将保持32位的大小。

    #include 
    #include 
    using namespace std;
    int main() {
        int L1 = 512;
        bitset<32> L2(L1);  // 创建了一个包含32位的位集合,并将其初始化为512
        for(int i=0; i<=100; i++){
            cout << (L2>>i).to_ulong() << endl;
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    云原生数据库的到来
    Intel Locked Atomic Operations
    AI电销机器人系统源码部署之:freeswitch安装Linux
    算法和数据及结构--稀疏数组
    基于网络数据流的未知密码协议逆向分析
    『无为则无心』Python面向对象 — 54、重写和super()函数
    探索互联世界的灯光艺术:FastLED库详细介绍及应用实例
    论文阅读疑惑,算法问题,求余,控制问题
    某工控图片上传服务 CPU 爆高分析
    langflow agent 资料
  • 原文地址:https://blog.csdn.net/Scott0902/article/details/133031034