【问题标题】:Right Shift in C++ giving unusual results (unsigned 64-bit)C++ 中的右移给出不寻常的结果(无符号 64 位)
【发布时间】:2014-11-22 16:23:17
【问题描述】:

我正处于可怕的位移世界中。我有以下代码:

我正在转移这个号码:140638023551944 >> 5。

根据http://www.binaryhexconverter.com/decimal-to-binary-converter 140638023551944 的二进制表示是

1000011000011111011101000111

右移 5,我预计:0000010000110000111110111010

但是,我得到的是 4394938235998,即 111111111101000110101110110111110001011110。

在我看来,这个数字与原来的数字几乎没有任何关系。我没有看到另一个存在的模式。太离奇了。

代码大致如下:

uint64_t n, index, tag;
uint64_t one = 1;
uint64_t address = 140638023551944;
/*left shift to get index into the last index.length() number of slots*/               
cout << "original address is " << address << " " << "\n";
n = (address >> 5);
cout << "after right shifting away offset bits " << n << "\n";

“地址”填充了正确的整数 140638023551944。我已经验证过了。

这是什么奇怪的行为?与本模拟器一致:http://www.miniwebtool.com/bitwise-calculator/bit-shift/?data_type=10&number=140638023551944&place=5&operator=Shift+Right!但我很确定右移不应该那样工作!

【问题讨论】:

  • address是什么类型?
  • 您的十进制到二进制转换不正确。 28 位二进制数当然不足以保存与 15 位十进制数相同的值。
  • 您的“参考”似乎确实是错误的,因为我的计算器给出了 4.394938236×10¹² 作为 140638023551944 / 32 的答案。换句话说,您的 C++ 代码给出了正确的答案。跨度>
  • 看起来差不多。您用来获取二进制数的狡猾网站无法处理 64 位值 - 它显示“最大值为 4294967295”。
  • 我真的看不出网站有什么问题。很清楚的说输入框上方的最大允许值

标签: c++ binary-operators


【解决方案1】:
// EVERYTHING WORKS CORRECTLY!

#include <cassert>   // assert()
#include <iostream>  // cout
#include <cstdint>   // UINT64_MAX

using namespace std;

int main() {
    uint64_t n, index, tag;
    uint64_t one = 1;
    uint64_t address = 140638023551944;
    /*left shift to get index into the last index.length() number of slots*/
    cout << "original address is " << address << " " << "\n";
    n = (address >> 5);
    cout << "after right shifting away offset bits " << n << "\n";

    {   // Everything works correctly!
        assert( 140638023551944>>5 == 140638023551944/32 );
        assert( 140638023551944>>5 == 4394938235998 );

        assert( 140638023551944/32 == 4394938235998 );
        assert( 140638023551944 < UINT64_MAX );
    }
}

【讨论】:

  • OP 中的代码运行良好。将问题标记为拼写错误/不再可重现:请参阅 OP 上的 cmets。
猜你喜欢
  • 1970-01-01
  • 2019-08-03
  • 1970-01-01
  • 1970-01-01
  • 2014-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多