c - 64 位整数的 8 位按位

标签 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 位。

任何人都可以根据数组 x 帮助实现 ROT(a,b) 吗?

谢谢

最佳答案

无论底层处理器是 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 是您喜欢的样式)以确保只有 b 的 6 LSBits 有助于转换。任何更高的位都意味着循环移位的多次“旋转”。
((64 - b) & 63) 可以简化为 (-b & 63)

--

但是如果 OP 仍然希望“根据数组 unit8_t x[8] 实现 ROT(a,b)”:

#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;
  }
}

关于c - 64 位整数的 8 位按位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22848262/

相关文章:

c - RGB 到 RGB 加琥珀色

c - Codevision AVR 中的错​​误

c - 将数字输入到avr中的寄存器中

java - 将 byte[] 转换为 short[],使得每个 short 元素包含 13 位数据

使用微 Controller 更改信号的相位值

c - C 中打印所有 32 位数字序列的函数

c - 如何抑制来自 gpgme 的 valgrind 警告?

c - "allowed"什么时候不释放动态分配的内存?

c++ - 使用位的标志

c++ - 如何递减一个位串?