C中的按位旋转函数

时间:2019-07-13 12:20:33

标签: python c

我需要将python函数转换为c。在c中,所有按位运算符似乎都相同,所以我认为我几乎可以复制代码并添加分号。这是python代码:

def ROTR(x, n, w=32):
    return ((x >> n) | (x << w - n)) & ((1 << w) - 1)

这可以正常工作,在5上运行,移位1且w = 32产生2147483650。

这是我的c函数:

int ROTR(int x, int n, int w) {
    return ((x >> n) | (x << w - n)) & ((1 << w) - 1);
}

这将产生0,具有相同的参数。

我尝试将功能分开,但我不知道是什么原因导致了此错误。

1 个答案:

答案 0 :(得分:4)

在C中,发生溢出时int和其他有符号整数的左移未定义,负值的右移由实现定义。因此,使用32位w - n向左移动int = 32 − 1 = 31位5会有不确定的行为。

为避免这种情况,请使用无符号整数类型进行移位。虽然可以使用unsigned int,但最好包含<stdint.h>并使用具有特定宽度的类型,例如uint32_t

uint32_t ROTR(uint32_t x, int n, int w)
{
    return x >> n | x << w-n;
}

此外,未定义移位大于或等于左操作数宽度的量,因此当1 << w为32位且w为32位时,int未定义。使用((1 << w) - 1)进行掩蔽的尝试也可能是不必要的;当移位的左操作数和/或函数返回类型为无符号整数类型时,将自动执行求值,就像被屏蔽一样。 (如果您希望该函数支持比其标称类型更窄的词,则掩码可能会有用。但是,您必须仔细构造它以避免未定义的行为,或者必须有条件地应用它,而不是在{{1} }是标称类型的宽度。)