如何删除十六进制数字右侧的X位



我正在处理缓存问题,需要将地址拆分为标记/set/offset。例如,我的地址为0xFFFFFE7D6C5B4333,例如偏移量包含5位(偏移量是地址右侧的第一个块(。然后,我必须将十六进制地址转换为二进制,删除前5位并将其转换回十六进制。这个过程可能需要一些时间,并且可能导致一些错误。如果偏移比特的数量是4*c格式,那么这可能很容易,因为我只需要从十六进制代码中删除第一个右c数字。

当偏移比特的数量不是格式4*c(例如5(时,有更好的方法吗?

例如,对于0xFFFFFE7D6C5B4333,我们得到:

11111111111111111110 0111 1101 0110 1100 0101 1011 0100 0011 0011

我们去掉前五个比特,得到:

11111111111111111110 0111 1101 0110 1100 0101 1011 0100 0011 001

返回十六进制:0x7FFFFF3EB62DA19

我建议转换为十进制(或二进制(数字,移位,然后再转换回来。问题是你使用的是大整数。大多数编程语言都支持任意大整数。例如,PHP有一个BC库。使用它,我可以在BC中快速编写在十六进制和十进制之间转换的函数。我可以通过多次除以2来写一个移位。然后,我可以执行你的例子。它本质上是三个函数调用:bchexdec、bcshift和bcdecex。

<?php
$hex = "FFFFFE7D6C5B4333";
print "HEX = $hexn";
$dec = bchexdec($hex);
print "DEC = $decn";
$dec = bcshift($dec,5);
print "DEC = $decn";
$hex = bcdechex($dec);
print "HEX = $hexn";
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;
}
?>

所以,您的问题实际上是用您想要使用的任何编程语言编写这三个函数。然后,如果您经常这样做,请编写一个函数来封装这三个函数调用。

最新更新