如何高效反转一个整数的所有比特位(C语言实现)

在嵌入式开发、底层系统编程和算法优化中,经常需要对数据进行位操作。其中,反转一个整数的所有比特位是一个常见的需求,例如用于网络传输、图像处理、加密解密等领域。

本文将带你一步步实现一个高效的 通用比特位反转函数,支持 uint8_tuint16_tuint32_tuint64_t 类型,并使用 C 语言的 _Generic 关键字实现类似“泛型”的功能,让代码更简洁、易用。


🎯 目标

  • 实现一个函数,能够反转任意大小整数的所有比特位。
  • 支持 uint8_tuint16_tuint32_tuint64_t 类型。
  • 高效无循环,使用分治法快速完成位反转。
  • 提供二进制打印辅助函数,方便调试和观察结果。

🔁 反转比特位的基本思路

要将一个整数的比特位完全反转,比如:

输入: 0b10100000 (0xA0)
输出: 0b00000101 (0x05)

常规做法是通过循环逐个提取每一位并拼接,但这种方式效率不高。我们采用一种 位运算 + 分治策略 的方法,可以在固定轮次内完成反转,非常高效。


#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

// 反转8位
uint8_t reverse_bits8(uint8_t n) {
	n = (n & 0x55) << 1 | (n >> 1 & 0x55);
	n = (n & 0x33) << 2 | (n >> 2 & 0x33);
	n = (n & 0x0F) << 4 | (n >> 4 & 0x0F);
	return n;
}

// 反转16位
uint16_t reverse_bits16(uint16_t n) {
	n = ((n & 0x5555) << 1) | ((n >> 1) & 0x5555);
	n = ((n & 0x3333) << 2) | ((n >> 2) & 0x3333);
	n = ((n & 0x0F0F) << 4) | ((n >> 4) & 0x0F0F);
	n = ((n & 0x00FF) << 8) | ((n >> 8) & 0x00FF);
	return n;
}

// 反转32位
uint32_t reverse_bits32(uint32_t n) {
	n = ((n >> 1) & 0x55555555) | ((n << 1) & 0xAAAAAAAA);
	n = ((n >> 2) & 0x33333333) | ((n << 2) & 0xCCCCCCCC);
	n = ((n >> 4) & 0x0F0F0F0F) | ((n << 4) & 0xF0F0F0F0);
	n = ((n >> 8) & 0x00FF00FF) | ((n << 8) & 0xFF00FF00);
	n = ((n >> 16) & 0x0000FFFF) | ((n << 16) & 0xFFFF0000);
	return n;
}

// 反转64位
uint64_t reverse_bits64(uint64_t n) {
	n = ((n >> 1) & 0x5555555555555555) | ((n << 1) & 0xAAAAAAAAAAAAAAAA);
	n = ((n >> 2) & 0x3333333333333333) | ((n << 2) & 0xCCCCCCCCCCCCCCCC);
	n = ((n >> 4) & 0x0F0F0F0F0F0F0F0F) | ((n << 4) & 0xF0F0F0F0F0F0F0F0);
	n = ((n >> 8) & 0x00FF00FF00FF00FF) | ((n << 8) & 0xFF00FF00FF00FF00);
	n = ((n >> 16) & 0x0000FFFF0000FFFF) | ((n << 16) & 0xFFFF0000FFFF0000);
	n = ((n >> 32) & 0x00000000FFFFFFFF) | ((n << 32) & 0xFFFFFFFF00000000);
	return n;
}

// 根据变量大小自动调用对应函数
#define reverse_bits(x) _Generic((x),         \
uint8_t:  reverse_bits8,                  \
uint16_t: reverse_bits16,                 \
uint32_t: reverse_bits32,                 \
uint64_t: reverse_bits64                  \
)(x)

// 打印二进制辅助函数(适用于任意位数)
void print_binary(void* data, size_t size) {
	uint8_t* bytes = (uint8_t*)data;
	for (int i = size - 1; i >= 0; i--) {
		for (int j = 7; j >= 0; j--) {
			printf("%d", (bytes[i] >> j) & 1);
			if (j == 4 || j == 0) printf(" ");
		}
		printf(" ");
	}
	printf("\n");
}



int main() {
	uint8_t  a = 0b10100000;
	uint16_t b = 0xA000;
	uint32_t c = 0xA0000000;
	uint64_t d = 0xA000000000000000;
	
	printf("原始值 a: ");
	print_binary(&a, sizeof(a));
	uint8_t ra = reverse_bits(a);
	printf("反转后 a: ");
	print_binary(&ra, sizeof(ra));
	
	printf("\n原始值 b: ");
	print_binary(&b, sizeof(b));
	uint16_t rb = reverse_bits(b);
	printf("反转后 b: ");
	print_binary(&rb, sizeof(rb));
	
	printf("\n原始值 c: ");
	print_binary(&c, sizeof(c));
	uint32_t rc = reverse_bits(c);
	printf("反转后 c: ");
	print_binary(&rc, sizeof(rc));
	
	printf("\n原始值 d: ");
	print_binary(&d, sizeof(d));
	uint64_t rd = reverse_bits(d);
	printf("反转后 d: ");
	print_binary(&rd, sizeof(rd));
	
	return 0;
}

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值