64位整数的8位按位

时间:2014-04-03 20:25:23

标签: c bit-manipulation avr

我想实现64位整数的按位循环移位。

ROT(a,b)会将位置i的位移到位置i+b。 (a是64位整数)

但是,我的avr处理器是一个8位处理器。因此,为了表达a,我必须使用 unit8_t x[8]

  • x[0]a的8个最高位。
  • x[7]a的8个最低有效位。

任何人都可以帮助在数组ROT(a,b)方面实施x吗?

谢谢

3 个答案:

答案 0 :(得分:3)

如果底层处理器是64位,8位或1位,则不会产生功能差异。如果编译器符合要求 - 你很高兴。使用uint64_t。代码不“必须使用unit8_t”,因为处理器是8位的。

uint64_t RPT(uint64_t a, unsigned b) {
  return (a << (b & 63))  |  (a >> ((64 - b) & 63));
}

为显性而添加额外() & 63(或%64你喜欢那种风格)加入以确保只有6个LSBits的b有助于转变。任何更高的位只是意味着循环移位的多次“旋转” ((64 - b) & 63)可以简化为(-b & 63)

-

但是如果OP仍然希望“在数组ROT(a,b)的术语中实现unit8_t x[8]”:

#include <stdint.h>

// circular left shift.  MSByte in a[0].
void ROT(uint8_t *a, unsigned b) {
  uint8_t dest[8];
  b &= 63;

  // byte shift
  unsigned byte_shift = b / 8;
  for (unsigned i = 0; i < 8; i++) {
    dest[i] = a[(i + byte_shift) & 7];
  }

  b &= 7; // b %= 8;  form bit shift;
  unsigned acc = dest[0] << b;
  for (unsigned i = 8; i-- > 0;) {
    acc >>= 8;
    acc |= (unsigned) dest[i] << b;
    a[i] = (uint8_t) acc;
  }
}

@vlad_tepesch建议一个强调AVR 8位性质的解决方案。这是一次未经考验的尝试。

void ROT(uint8_t *a, uint8_t b) {
  uint8_t dest[8];
  b &= 63;  // Could be eliminated as following code only uses the 6 LSBits.

  // byte shift
  uint8_t byte_shift = b / 8u;
  for (uint8_t i = 0; i < 8u; i++) {
    dest[i] = a[(i + byte_shift) & 7u];
  }

  b &= 7u; // b %= 8u;  form bit shift;
  uint16_t acc = dest[0] << b;
  for (unsigned i = 8u; i-- > 0;) {
    acc >>= 8u;
    acc |= (uint8_t) dest[i] << b;
    a[i] = (uint8_t) acc;
  }
}

答案 1 :(得分:1)

为什么不将工作留给编译器而只是实现一个函数

uint64_t rotL(uint64_t v, uint8_t r){
  return  (v>>(64-r)) | (v<<r)
}

答案 2 :(得分:0)

我认为x(i)是8位。 向左旋转n次 来自X(i,j)的每个位,其中i是索引数组x(0) - &gt; X(7)                      j是元素中的位位置

然后这一位将结束 Y((i + n)/ 8,(i + n)&amp; 7) 这将处理高达63的旋转 任何数字&gt; 63,你只需要修改它。