为什么把uint32_t换成int后输出就变了呢?

/*颠倒二进制位:颠倒给定的 32 位无符号整数的二进制位*/ uint32_t reverseBits(uint32_t n) { uint32_t…
关注者
13
被浏览
51,020
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

你这个程序不止是int的问题……

先说int,ans变成int程序就不正确的核心愿意是,32位的int类型没法表示出正确的结果,也就是溢出了。32位的int能表示的最大的数比你的正确答案要小,所以你的程序结果不可能正确。

至于你得到的那个0x80000000的结果,是没有意义的。C/C++里,signed integer的overflow是undefined behavior。按照你写这个程序体现出来的对C/C++的熟悉程度,你可能还不知道什么是undefined behavior。这是个很有趣的大坑,有空可以研究一下。简单的说就是,在C和C++里,你的某一些操作可能会让你的程序发生任何情况(包括电脑爆炸)。signed integer(有符号整数)的overflow就是其中一种常见的情况。

也就是说,在你现在这个程序下,这个函数返回多少都是可能的(是由编译器决定的)。

但是这个程序不光是这个问题,首先你不应该使用pow这个函数。不使用它有两个原因:

  1. pow这个函数是double的输入输出,在位运算或者说整型运算中引入浮点数本身就是彻头彻尾的错误,很可能不经意间引入一些比较偏僻的由计算误差带来的问题。
  2. 在计算2的n次方时,pow理论上可能比移位要慢很多(尽管compiler的优化可以解决这个问题)

最后,位运算的题目,很少是要回归到它们代表的「数」去计算的。你看待这个题目的角度不应该是「32个bit表示的数」,而是单纯的「32个bit」。如果以这个角度来看问题,肯定就不会出现每个bit要乘以2的多少次方再加起来这种算法了。

这个题目比较直观的算法应该是,直接把bit倒序一个一个扔进另外一个32bit的容器。

/*颠倒二进制位:颠倒给定的 32 位无符号整数的二进制位*/
uint32_t reverseBits(uint32_t n) {
    uint32_t ans = 0;
    for (int i = 0; i < 32; i++) {
        ans <<= 1;
        ans |= (n & 1);
        n >>= 1;
    }
    return ans;
}