我需要将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,具有相同的参数。
我尝试将功能分开,但我不知道是什么原因导致了此错误。
答案 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} }是标称类型的宽度。)