2014-03-31 187 views
0

我试图应用n位的圆形位位移ç循环移位64位使用< <和>>运算符(1和62之间变化),但其结果是不出来按预期.. 。工作不正常

它用1个圆形的变化,但不多(我没有验证所有的)...

uint64_t array[25]; 
for(i=0;...) 
    array[i] = ((s[n] << n) | (s[i] >> (64-n))); 

例效果很好: --->竟将这一点:00: 00:02:26:00:00:00:2D --->我得到这个:00:80:80:09:00:00:40:0B

这是没有任何意义的,因为我甚至无法理解发生了什么。

任何帮助,将不胜感激。我试图做这32位计算机上...也许这有事情做与...

非常感谢;)

+1

我们不知道所有变量的类型,我觉得倾向于猜测。至少你应该把它包装在一个函数中,并展示整个函数。当然,我们不需要看到长度为25的数组来处理这个问题。 SSCCE如何? –

+0

是的,请给我们一个例子的小函数,你期望输入和输出是什么? – Salgar

回答

0

确保类型的*s无符号否则你会得到符号扩展的位移。您也可以使用s[n] << n而不是s[i] << n

此外,如果您是在X86-64你可能要考虑使用的处理器指令:

uint64_t temp = s[i]; 
asm ("rolq %0, %%cl" 
    , "+r" (temp) 
    : "c" ((uint8_t)n)); 
array[i] = temp; 
+0

你是对的,但使用内联汇编在这里有点矫枉过正。编译器将优化你的东西(实际上将它翻译成ROL或ROR指令)。此外,它使代码不可读取,更好地坚持<< | >>行,并添加一些评论。 –

+0

你并不需要那么做,GCC认识到旋转模式,并发出和实际的'rol'(Clang和ICC也是如此)。我不知道MSVC,但它不喜欢GCC风格的内联asm,所以这对此无济于事。 – harold

0

您应该始终如一地使用索引变量对指数和移位计数转移。然后事情可能会解决。

2

使用S [I],而不是S [N]:

uint64_t array[25]; 
for(i=0;...) 
    array[i] = ((s[i] << n) | (s[i] >> (64-n))); 

您索引变量混合在一起i和移位跨度n的意义不大在此上下文中。我假设s是:

uint64_t s[25]; 

不,这不是一个架构问题... uint64_t中既是在x86和IA64家庭无符号的64位整数。在后者的64位整数由CPU本地处理,在前者中你必须使用更多的寄存器来做同样的事情......