当您执行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位数之外的所有数字?
答案 0 :(得分:3)
'不幸的是,这根本没有效果。'
这可能是因为你在签名 int上进行了计算。尝试将值转换为unsigned
,或者只是忘记余数运算符%
并使用按位掩码:
displacement & 0xFF;
displacement & 255;
表示两位十六进制数字或
displacement & 0xFFF;
displacement & 4095;
三位数。
编辑 - 一些解释
详细答案将会很长......您需要了解C中使用的数据类型(特别是int
和unsigned int
,这是最常用的两个Integral types) ,可以在Two's complement代码中表示的那些类型的值范围及其内部表示。还有Integer overflow和Hexadecimal 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完全按照您的要求执行:删除值的较高部分,只留下所需的两个或三个低阶十六进制数。