十六进制删除前导数字

时间:2014-04-23 17:11:00

标签: c

当您执行0x01AE1 - 0x01AEA = fffffff7之类的操作时。我只想要最后3位数。所以我使用模数技巧来删除额外的数字。位移用十六进制值填充。

  int extra_crap = 0; 
  int extra_crap1 = 0; 
  int displacement = 0;
  int val1 = 0;
  int val2 = 0;

  displacement val1 - val2;
  extra_crap = displacement % 0x100;
  extra_crap1 = displacement % 256;
  printf(" extra_crap is %x \n", extra_crap);
  printf(" extra_crap1 is %x \n", extra_crap1);

不幸的是,这根本没有效果。有没有其他方法可以删除除最后3位数之外的所有数字?

1 个答案:

答案 0 :(得分:3)

'不幸的是,这根本没有效果。'

这可能是因为你在签名 int上进行了计算。尝试将值转换为unsigned,或者只是忘记余数运算符%并使用按位掩码:

displacement & 0xFF;
displacement & 255;

表示两位十六进制数字或

displacement & 0xFFF;
displacement & 4095;

三位数。

编辑 - 一些解释

详细答案将会很长......您需要了解C中使用的数据类型(特别是intunsigned int,这是最常用的两个Integral types) ,可以在Two's complement代码中表示的那些类型的值范围及其内部表示。还有Integer overflowHexadecimal system

然后,您可以轻松了解数据发生的情况:减去0x01AE1 - 0x01AEA,即6881 - 6890,得到-9的结果,其中包含2位编码的32位有符号整数&# 39;补码并以十六进制打印为FFFFFFF7。 MINUS NINE除以256得到商ZERO和Remainder MINUS NINE,因此余数运算符%给出了精确正确的结果。你所谓的'根本没有效果' 只是因为你不了解你实际在做什么。

我上面的答案(变体1)不是任何一种魔法,而只是一种强制计算正数的方法。将值转换为unsigned类型会使程序将0xFFFFFFF7解释为4294967287,除以265(十六进制为0x100),得到商16777215(0xFFFFFF)和余数247(0xF7)。变体2根本没有分割,只是掩盖了#39;那些必要的位:数字255和4095包含8和12个低位,等于1(分别为十六进制0xFF和0xFFF),因此bitwise AND完全按照您的要求执行:删除值的较高部分,只留下所需的两个或三个低阶十六进制数。