如何通过位掩码实现十进制到四进制的C语言转换
问题背景
我正尝试编写程序,通过位掩码(bit masking)方法实现十进制到四进制的转换。为了理解位掩码的工作逻辑,我首先编写了十进制转二进制的实现代码,具体如下:
#include <stdio.h> void binary(unsigned int num) { int i; unsigned temp, mask=1; mask<<=31; for(i=0; i<32; i++) { temp=num&mask; printf("%d", temp>>(31-i)); mask>>=1; } } int main () { int n; printf("Enter a number:\n"); scanf("%d", &n); binary(n); return 0; }
随后我尝试沿用相同的思路编写四进制转换函数,目前写出的代码框架如下,其中temp变量的赋值逻辑尚未明确:
void base4(unsigned int num) { int i; unsigned temp, mask=3; mask<<=15; for(i=0; i<16; i++) { temp= // <<<<==== ??? printf("%d", temp>>(15-i)*2); mask>>=1; } }
我了解四进制的每1位对应2个二进制位,例如数值22对应的二进制、四进制表示对应关系如下:
.... 0 0 1 1 2 (base4) .... 00 00 01 01 10 (bin)
但我无法将这个对应规律应用到之前二进制转换的实现思路中。
实现方案
你的二进制转码逻辑本身完全成立,沿用到四进制只需要对齐「1位四进制对应2位二进制」的规则,修正两处移位错误即可,temp的赋值逻辑和二进制版本完全一致:
- temp赋值直接写
num & mask即可,作用是用mask取出当前要处理的2个二进制位的值 - 初始mask移位值错误:原代码写
mask<<=15,3(二进制11)左移15位只能覆盖第15、16位二进制位,没有对齐32位无符号数的最高两位,需要改成mask<<=30 - 循环内mask移位步长错误:原代码写
mask>>=1每次只移动1个二进制位,会导致mask错位,需要改成mask>>=2,每次跳过2个二进制位,刚好对齐下一个四进制位
你代码里printf的移位逻辑temp>>(15-i)*2是正确的,不需要修改。修正后的完整base4函数如下:
void base4(unsigned int num) { int i; unsigned temp, mask=3; mask<<=30; // 初始mask覆盖最高两位二进制位(第31、30位) for(i=0; i<16; i++) { temp = num & mask; // 取出当前两位的数值 printf("%d", temp >> ( (15-i)*2 ) ); mask >>= 2; // 每次右移2位,对齐下一个四进制位 } }
验证说明:传入数值22(二进制10110)时,函数输出的16位四进制字符串末尾三位为112,和你给出的对应关系完全匹配。如果不需要输出前导零,可以在循环中加标记位,遇到第一个非0值后再开始打印。
内容的提问来源于stack exchange,提问作者Buffer
相关产品推荐
相关产品推荐

