2016-11-10 5 views
0

Im пытается получить бит 6 - 15 шестнадцатеричного значения в C++. Im использует & 0xFFC0, и когда я печатаю значение этих битов im, получая значения более 1024. Но поскольку его 10 бит самое высокое значение, к которому можно получить доступ, равно 1024, правильно?получение определенных битов из шестнадцатеричного значения

У меня 32 битный адрес, который тег = 31 до 16 индекс = от 15 до 6 смещение = от 5 до 0

мой код выглядит следующим образом

long long offset = address & 0x1F; 
long long index = address &0xFFC0; 
long long tag = address & 0xFFFF0000; 
+2

Кажется, что вам не хватает операций * shift *, чтобы довести это значение до требуемого диапазона. – WhozCraig

+0

'0xFFFF0000' +' 0xFFC0' + '0x1F' =' 0xFFFFFFDF'. Просто подумал, что я бы сказал об этом. –

ответ

0

0xFFC0 является 65472, так что, очевидно

address & 0xFFC0

может быть 65472 (более 1024). Что вам нужно, чтобы получить I-й бит является

address >> i & 1 

Какие сдвигает адрес право I бит, а теперь немного вы заинтересованы в это первый бит числа. Затем вы получаете его значение и записывая его с помощью 1.

+0

Я не совсем понимаю, вы можете объяснить немного больше, пожалуйста? –

+0

@ user3678290 Что вы не поняли? – matanso

+0

, так что, если я сдвигаю адрес 16 бит, чтобы получить первый бит индекса в качестве первого бита адреса, тогда я хочу получить значение следующих 10 бит –

0

Поскольку ваш адрес представляет собой 32-разрядное битовое поле, я бы предложил создать простую структуру-оболочку, которая может быть построена и/или преобразована в uint32_t.

struct Addr { 
    uint32_t offset : 6; 
    uint32_t index : 10; 
    uint32_t tag : 16; 

    Addr(uint32_t addr); 

    operator uint32_t(); 

    void output(); 
}; 

Addr::Addr(uint32_t addr) 
    : offset(addr & 0x3F), 
    index((addr & 0xFFC0) >> 6), 
    tag((addr & 0xFFFF0000) >> 16) 
{} 


Addr::operator uint32_t() { 
    return ((offset) | (index << 6) | (tag << 16)); 
} 


void Addr::output() { 
    // Weird tabs & spacing are to guarantee proper formatting (in GCC testing environment). 
    std::cout << "Offset: " << std::dec << offset << "\t\t(" << std::hex << offset << ")\n" 
       << "Index: " << std::dec << index << " \t(" << std::hex << index << ")\n" 
       << "Tag: " << std::dec << tag << (tag > 999 ? "\t(" : "\t\t(") 
                   << std::hex << tag << ")\n"; 

} 

Это позволяет использовать адрес в виде 32-битного значения, а также изолировать каждый компонент как отдельную переменную.

Это позволяет:

  • Построить из uint32_t:

    Addr addr = 0xFFFFFFFF; 
    
  • Использование в качестве uint32_t:

    std::cout << std::hex << static_cast<uint32_t>(addr) << '\n'; 
    
  • Присвоить полей индивидуально:

    addr.offset = 0x1A; 
    addr.index = 0x32F; 
    

в действии here или here, если вы хотите, чтобы вывод шестигранного быть выстроен с его фактическим местоположением в адресе.

Смежные вопросы