C 清除常量低位字节的按位表达式
我正在编写可能在不同字长(32位、64位等)的体系结构上运行的代码,我希望清除值的低位字节。有一个宏(MAX)被设置为单词的最大值。例如,在32位系统上,对于无符号值,MAX=0xFFFFFFFF,在64位系统上MAX=0xffffffffffff。如果我有一个字大小的变量,可能是有符号的,也可能是无符号的,那么如何用一个表达式清除变量的低位字节(无分支) 我的第一个想法是:C 清除常量低位字节的按位表达式,c,bit-manipulation,C,Bit Manipulation,我正在编写可能在不同字长(32位、64位等)的体系结构上运行的代码,我希望清除值的低位字节。有一个宏(MAX)被设置为单词的最大值。例如,在32位系统上,对于无符号值,MAX=0xFFFFFFFF,在64位系统上MAX=0xffffffffffff。如果我有一个字大小的变量,可能是有符号的,也可能是无符号的,那么如何用一个表达式清除变量的低位字节(无分支) 我的第一个想法是: value & ~( MAX - 0xFF ) 但这似乎不适用于有符号值。我的另一个想法是: value =
value & ~( MAX - 0xFF )
但这似乎不适用于有符号值。我的另一个想法是:
value = value - (value & 0xFF)
它的缺点是需要堆栈操作。如何
value & ~((intptr_t)0xFF)
首先,您需要一个掩码,该掩码所有位都打开,但低阶字节的位除外
MAX ^ 0xFF
这将0xFF
转换为与MAX
相同的类型,然后使用该值执行异或运算。因为MAX
具有所有低阶位1
,因此这些位随后变为0
,而高阶位保持不变,即1
然后你必须把面具盖在你感兴趣的价值上
value & ( MAX ^ 0xFF )
若要清除低位字节,不知道整数类型宽度可能会导致错误代码。所以代码应该小心 考虑以下情况,
value
比int/unsigned
宽0xFF
是一个值为255的int
常量~0xFF
则是该值及其位反转。如果对公共2进行补充,则其上限位设置为FF…FF00时为-256-256转换为更宽的有符号类型时保留其值和模式FF…FF00-转换为更宽的无符号类型的256变为Uxxx\u MAX+1-256
,位模式为FF…FF00。在这两种情况下,和
将保留高位并清除低位8
value_low_8bits_cleared = value & ~0xFF;
另一种方法是使用无符号数学执行所有屏蔽操作,以避免
int
math和int
编码的意外属性
下面的代码不涉及符号扩展,int
overflow。一个优化的编译器肯定会发出一个简单而有效的代码掩码。此外,不需要对与值
相对应的正确匹配最大值进行编码
value_low_8bits_cleared = (value | 0xFFu) ^ 0xFFu;
以下是清除低位8位的简单方法:
value &= ~0xFF;
我正在编写可以在不同字数的体系结构上运行的代码
(32位、64位等)我想清除值的低位字节
有一个宏(MAX)被设置为单词的最大值。所以
例如,在32位系统上,MAX=0xFFFFFFFF,在64位系统上
对于无符号值,系统最大值=0xFFFFFFFFFFFFFF
尽管C语言的设计使得实现可以考虑机器词的大小,但该语言本身并没有机器词的固有含义。C关心的是类型,这就不同了
无论如何,我完全按照您的话来理解,您将macroMAX
的替换文本作为您给出的两个备选文本之一,具体取决于机器的体系结构。请注意,当替换文本被解释为整数常量时,其类型在C实现之间可能会有所不同,甚至可能取决于编译器选项
如果我有
字大小的变量,可以是有符号的或无符号的,如何清除
具有单个表达式的变量的低位字节(无分支)
我认为需要一个表达式而不能显式地考虑实际类型的值
的唯一原因是希望在宏本身中使用该表达式。在这种情况下,您需要特别注意类型转换,尤其是当您必须考虑签名类型时。这会使您的MAX
宏不适合用于您的目的
我倾向于建议一种不同的方法:
(value | 0xFF) ^ 0xFF
常量
0xFF
将被解释为(有符号)int
带正值。如果value
的类型不小于int
,则0xFF
的两种外观都将转换为该类型,而不改变值,无论该类型是有符号的还是无符号的。此外,每个操作和整个表达式的结果的类型与value
相同,因此不会发生意外的转换。在任何(8位字节)上使用~0xFF
进行ANDing,以清除低位字节体系结构。请注意,MAX
的扩展类型独立于表达式中的其他变量和值的类型,例如您所呈现的类型。不过,总的来说,我不太清楚你想克服什么问题。我一直在想,有些维度我还没有意识到,没有一个字大小的变量可以是有符号的,也可以是无符号的。你要么签字,要么不签字。问题到处都是。首先,你说你正在使用一个常数。然后它突然变成了一个可能是“有符号或无符号”的变量。那么,它是什么:变量还是常数?你需要下决心。首先,从图片中去掉“签名”。不允许签名。您仅使用未签名的。如果您需要签名,您将在以后转换结果。在实践中,这可能在任何地方都适用。然而,重要的是,它可能涉及将value
转换为typeintptr\u t
,并可能根据表达式的使用方式进行其他转换。与其使用intptr\u t
,不如使用uintmax\u t
对MAX^0xFF
的描述不正确。低阶位被反转。如果MAX
没有以0xFF
结尾,则它将不起作用。可以工作的是value&(value^0xFF)
@EugeneSh.,MAX
在问题中被描述为类型的最大值。因此它有一个