按整数值移位
bit-shifting by an integer value
此代码用于缓存模拟器项目 - 我正在尝试从内存地址中提取某些位。当我尝试使用 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 位无符号长整数,而我只移动了 48 位:
warning: left shift count >= width of type [enabled by default]
在此先感谢您的帮助。
所有整数文字值都是 int
类型,除非您指定前缀,例如1ULL
.
这意味着 1<<33
将 32 位有符号值移动 33 步。你需要做 1ULL << 33
.
我认为问题是:常量 1 正在转换为整数类型(4 字节 32 位)。但是,您确实左移了 33 位(超过整数类型),在这种情况下,我们应该在左移之前将 1 强制转换为 unsigned long 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);
此代码用于缓存模拟器项目 - 我正在尝试从内存地址中提取某些位。当我尝试使用 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 位无符号长整数,而我只移动了 48 位:
warning: left shift count >= width of type [enabled by default]
在此先感谢您的帮助。
所有整数文字值都是 int
类型,除非您指定前缀,例如1ULL
.
这意味着 1<<33
将 32 位有符号值移动 33 步。你需要做 1ULL << 33
.
我认为问题是:常量 1 正在转换为整数类型(4 字节 32 位)。但是,您确实左移了 33 位(超过整数类型),在这种情况下,我们应该在左移之前将 1 强制转换为 unsigned long 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);