Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用int和移位执行逐位和_C++_Bit_Shift_Negative Number - Fatal编程技术网

C++ 使用int和移位执行逐位和

C++ 使用int和移位执行逐位和,c++,bit,shift,negative-number,C++,Bit,Shift,Negative Number,这个问题基于: 问题的根源是-我定义了一个enum,它表示不同的掩码。 并且需要使用enum(掩码)对变量进行和,然后将结果右移。 由于enum类型始终为int,因此该变量也被定义为int。但正如您所见,右移负数时出现问题。 如何解决这个问题呢?您可以先移位,然后逆移位掩码来解决这个问题。您可以先移位,然后逆移位掩码来解决这个问题。我建议您在移位之前将枚举的值静态强制转换为unsigned long。我认为这是您可以使用的最安全的选项。我建议您在移位之前将枚举的值静态强制转换为unsigned

这个问题基于: 问题的根源是-我定义了一个
enum
,它表示不同的掩码。 并且需要使用
enum
(掩码)对变量进行
,然后将结果右移。
由于
enum
类型始终为
int
,因此该变量也被定义为
int
。但正如您所见,右移负数时出现问题。
如何解决这个问题呢?

您可以先移位,然后逆移位掩码来解决这个问题。

您可以先移位,然后逆移位掩码来解决这个问题。

我建议您在移位之前将枚举的值静态强制转换为
unsigned long
。我认为这是您可以使用的最安全的选项。

我建议您在移位之前将枚举的值静态强制转换为
unsigned long
。我认为这是您可以使用的最安全的选项。

首先,
enum
类型并不总是
int
;在C++11中,您可以 甚至强制它为无符号类型。第二,即使 基础类型是
int
,您可以(也应该)自由转换为 从
未签名的
,没有真正的风险。例如,您可以过载
操作符&
因此:

MyEnum
operator&( MyEnum lhs, MyEnum rhs )
{
    return static_cast<MyEnum>(
        static_cast<unsigned>( lhs) & static_cast<unsigned>( rhs ) );
}
MyEnum
运算符&(MyEnum lhs、MyEnum rhs)
{
返回静态输出(
静态_-cast(左侧)和静态_-cast(右侧));
}

提取可能位于某个中间位置的字段:

int
getFieldX( MyEnum values )
{
    return static_cast<unsigned>(values & fieldXMask) >> fieldXOffset;
}
int
getFieldX(MyEnum值)
{
返回静态_cast(值和fieldXMask)>>fieldXOffset;
}
这将确保行为正确(并且一旦未签名的值 已移位,应转换为
int
,而不会丢失
首先,
enum
类型并不总是
int
;在C++11中,您可以 甚至强制它为无符号类型。第二,即使 基础类型是
int
,您可以(也应该)自由转换为 从
未签名的
,没有真正的风险。例如,您可以过载
操作符&
因此:

MyEnum
operator&( MyEnum lhs, MyEnum rhs )
{
    return static_cast<MyEnum>(
        static_cast<unsigned>( lhs) & static_cast<unsigned>( rhs ) );
}
MyEnum
运算符&(MyEnum lhs、MyEnum rhs)
{
返回静态输出(
静态_-cast(左侧)和静态_-cast(右侧));
}

提取可能位于某个中间位置的字段:

int
getFieldX( MyEnum values )
{
    return static_cast<unsigned>(values & fieldXMask) >> fieldXOffset;
}
int
getFieldX(MyEnum值)
{
返回静态_cast(值和fieldXMask)>>fieldXOffset;
}
这将确保行为正确(并且一旦未签名的值 已移位,应转换为
int
,而不会丢失
值)。

为什么不能将变量定义为
uint64\u t
?我想他想移动枚举值。@IvayloStrandjev-我想在和之后移动结果。您可以使枚举的基础类型不同。@AlexChamberlain-我定义它为int64\t,以便与int(枚举掩码)一致为什么您不能将变量定义为
uint64\t
?我想他想移动枚举值。@IvayloStrandjev-我想在和之后移动结果。您可以使枚举的基础类型不同。@AlexChamberlain-我定义它为int64\t以与int(枚举掩码)一致,这是最安全的,但如果计算机硬件不支持64位类型,并且您的枚举不需要64位类型,则可能会对性能造成重大影响。对于各种“重要”值,这是最安全的,但如果计算机硬件不支持64位类型,则可能会对性能造成重大影响,您的枚举不需要它们。对于各种“重要”值。@Yackov我也不需要。我已经使用上面的代码超过20年了。(如果你真的想稳妥行事,至少可以选择
uint\u t
,而不是
unsigned
。但对于大多数情况来说,
unsigned
就足够了。)@Yackov我也不这么认为。我已经使用上面的代码超过20年了。(如果你真的想稳妥起见,请至少转换为
uint\u t
,而不是
unsigned
。但在大多数情况下,
unsigned
就足够了。)