Как убрать бит X справа от шестнадцатеричного числа? - PullRequest
0 голосов
/ 12 июля 2020

Я занимаюсь вопросами кеширования, и здесь мне нужно разбить адрес на tag / set / offset. Например, у меня есть адрес 0xFFFFFE7D6C5B4333, и, например, смещение содержит 5 бит (смещение - это первый блок справа от адреса). Затем мне пришлось бы преобразовать шестнадцатеричный адрес в двоичный, удалить первые 5 бит и преобразовать обратно в шестнадцатеричный. Этот процесс может занять некоторое время и привести к ошибкам. Если бы количество битов смещения было в формате 4 *c, это могло бы быть легко, потому что я бы просто удалил первые правые c числа из шестнадцатеричного кода.

Есть лучший способ сделать это когда количество битов смещения не имеет формата 4 *c (например 5)?

Например, для 0xFFFFFE7D6C5B4333 мы получаем:

1111 1111 1111 1111 1111 1110 0111 1101 0110 1100 0101 1011 0100 0011 0011 0011

Убираем первые пять бит и получаем:

1111 1111 1111 1111 1111 1110 0111 1101 0110 1100 0101 1011 0100 0011 001

Вернуться в шестнадцатеричный: 0x7FFFFF3EB62DA19

1 Ответ

0 голосов
/ 12 июля 2020

Я предлагаю преобразовать в десятичное (или двоичное) число, сдвинуть и преобразовать обратно. Проблема в том, что вы используете большие целые числа. Большинство языков программирования поддерживают произвольно большие целые числа. Например, PHP имеет библиотеку B C. Используя это, я могу быстро написать функции для преобразования между шестнадцатеричным и de c в B C. Я могу записать сдвиг, разделив его на 2 несколько раз. Тогда я могу привести ваш пример. По сути, это три вызова функций: bchexde c, bcshift и bcdechex.

<?php
$hex = "FFFFFE7D6C5B4333";
print "HEX = $hex\n";
$dec = bchexdec($hex);
print "DEC = $dec\n";
$dec = bcshift($dec,5);
print "DEC = $dec\n";
$hex = bcdechex($dec);
print "HEX = $hex\n";

function bcshift($dec,$n) {
    for($i=0; $i<$n; $i++) {
        $dec = bcdiv($dec,"2");
    }
    return $dec;
}
function bchexdec($hex)
{
    $dec = 0;
    $len = strlen($hex);
    for ($i = 1; $i <= $len; $i++) {
        $dec = bcadd($dec, bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i))));
    }
    return $dec;
}
function bcdechex($dec) {
    $hex = '';
    do {
        $last = bcmod($dec, 16);
        $hex = dechex($last).$hex;
        $dec = bcdiv(bcsub($dec, $last), 16);
    } while($dec>0);
    return $hex;
}
?>

Итак, ваша проблема заключается в написании этих трех функций на любом языке программирования, который вы хотите использовать. Затем, если вы делаете это часто, напишите функцию, которая объединяет эти три вызова функций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...