bit-shifting by an integer value

别来无恙 提交于 2019-12-20 03:30:42

问题


This code is for a cache simulator project - I am trying to extract certain bits from a memory address. When I attempt to use int variables to do the bit shifting, I end up with an incorrect result, but when I use the numbers directly, my result is correct. I've been looking all over for an answer to this, but I can't find one. What is my issue here?

#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);

}

The output is:

Tag 1: fffeb509
Tag 2: 1

I am also getting a warning for the line that computes tag1 correctly, which doesn't make sense to me, since tag1 is a 64-bit unsigned long long int, and I am only shifting by 48 bits:

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

Thanks in advance for the help.


回答1:


All integer literal values are int type, unless you specify a prefix such as e.g. 1ULL.

That means that 1<<33 shifts a 32-bit signed value 33 steps. You need to do 1ULL << 33.




回答2:


I think the problem is: constant 1 is casting to integer type (4 bytes 32 bits). However, you do shift left 33 bits (exceed integer type), in this case we should cast 1 to unsigned long long int (8 bytes = 64 bits) before doing shift left:

#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);


来源:https://stackoverflow.com/questions/29803345/bit-shifting-by-an-integer-value

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!