按位整数移位

时间:2015-04-22 16:14:05

标签: c bit-shift

此代码用于缓存模拟器项目 - 我试图从内存地址中提取某些位。当我尝试使用int变量进行位移时,我得到的结果不正确,但是当我直接使用数字时,我的结果是正确的。我一直在寻找答案,但我找不到答案。我的问题在这里是什么?

#include <stdio.h>

void main(){

    unsigned long long int mem_addr = 0x7fff5a8487c0;

    int byte_offset_bits = 2;
    int block_offset_bits = 5;
    int index_bits = 8;
    int tag_bits = 33;

    unsigned long long int tag1 = (mem_addr&(((1<<33)-1)<<(2+5+8)))>>(2+5+8);
    unsigned long long int tag2 = (mem_addr&(((1<<tag_bits)-1)<<(byte_offset_bits + block_offset_bits + index_bits)))>>(byte_offset_bits + block_offset_bits + index_bits);

    printf("%s %llx\n", "Tag 1:", tag1);
    printf("%s %llx\n", "Tag 2:", tag2);

}

输出结果为:

Tag 1: fffeb509
Tag 2: 1

我也正在警告正确计算tag1的行,这对我没有意义,因为tag1是64位无符号long long int,而我只移位48位:< / p>

 warning: left shift count >= width of type [enabled by default]

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

所有整数文字值均为int类型,除非您指定前缀,例如1ULL

这意味着1<<33将32位有符号值移位33步。您需要1ULL << 33

答案 1 :(得分:0)

我认为问题是:常量1正在转换为整数类型(4字节32位)。但是,你确实向左移了33位(超过整数类型),在这种情况下我们应该在向左移位之前将1转换为无符号长long int(8字节= 64位):

#include <stdio.h>

void main(){

    unsigned long long int mem_addr = 0x7fff5a8487c0;

    int byte_offset_bits = 2;
    int block_offset_bits = 5;
    int index_bits = 8;
    int tag_bits = 33;
    unsigned long long int one = 1;
    unsigned long long int tag1 = (mem_addr&(((one<<33)-one)<<(2+5+8)))>>(2+5+8);
    unsigned long long int tag2 = (mem_addr&(((one<<tag_bits)-one)<<(byte_offset_bits + block_offset_bits + index_bits)))>>(byte_offset_bits + block_offset_bits + index_bits);

    printf("%s %llx\n", "Tag 1:", tag1);
    printf("%s %llx\n", "Tag 2:", tag2);