问题
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