欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

逆序输入数的二进制序列输出

程序员文章站 2022-03-08 15:29:58
...

题目

编写函数:
unsigned int reverse_bit(unsigned int value);
这个函数的返回值value的二进制位模式从左到右翻转后的值。
如:
在32位机器上25这个值包含下列各位:
00000000000000000000000000011001
翻转后:(2550136832)
10011000000000000000000000000000
程序结果返回:
2550136832

思路

二进制序列取出,按位与(&)1能够取出每一位二进制序列
比如20的二进制序列为00010100(32位我们这里只写出后八位)
与1与,取出0,将20的二进制序列右移一位(>>1)
重复上述过程,将取出来的每一位放入一个32个数字的数组,即为二进制序列
但是这种写法需要32次循环才能取出所有二进制序列,无论前面32位有多少个0
例如,如果一个二进制序列为:
10000000 00000000 00000000 00000000
此时这个二进制序列需要32次循环才能取出

优化

char为一个字节,可以将int的四个字节分别取出放入char
当char此字节为0,直接数组内对应二进制序列存为0,跳过挨个取位的过程
这里涉及到大端存储和小端存储的问题
小端存储即int的低字节部分存在内存地址的小地址部分
我们可以强转将数字的地址转为char *赋给一个char 的指针变量
举个例子:
int value = 25;
char * p = &(char *)value;
当这么取时,接下来p++就可以获取四个字节中的第二个字节,依次获取,一次取8位,如果8位表示0,跳过取每一位将序列存入数组过程
我给出的算法建立在小端存储的基础上,运行环境为Windows下的VS

实现代码

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <stdlib.h>

unsigned int reverse_bit(unsigned int value);

int main()
{
    unsigned int num = 0;
    printf("输入要倒转的数:");
    scanf("%d", &num);
    printf("\n%u\n", reverse_bit(num));
    system("pause");
    return 0;
}

unsigned int reverse_bit(unsigned int value)
{
    unsigned char *a;
    unsigned int arr[32] = { 0 };
    int i = 0, j = 31;
    unsigned int ret = 0;
    a = &(unsigned char *)value;//取出要倒序的数的地址,为了优化速度,这里使用char,一次处理8个比特位
    for (i = 0; i < 4; i++)
    {

        if (*a == 0)//优化速度,当该字节为0,直接跳过下面取位
        {
            a++;
            break;
        }
        for (j = 8 * i; j < 8 * (i + 1); j++)//非0,与1来&按位取出二进制串
        {
            if (((*a) & 1) == 1)
            {
                arr[j] = 1;
            }
            *a = *a >> 1;
        }
        a++;
    }
    printf("倒转的二进制序列:\n");
    for (i = 0; i < 32; i++)
    {
        printf("%d", arr[i]);
        if (i % 8 == 7)
            printf(" ");
    }
    for (i = 0; i < 31; i++)//将数组里存的二进制序列转成无符号数
    {
        ret = ret + arr[i];
        ret = ret * 2;//此处之所以只循环31次,若循环32次,第一位会丢失
    }
    ret = ret + arr[i];//加上最后一位二进制序列
    return ret;
}

本文为学习过程中碰到的比较有意思的题目,也欢迎各路高手提出更好的解决方法在下方评论

也欢迎各位到我的github下下载更多练习代码,如果对上述有疑问可以在下方评论