计算机中的灵魂世界—二进制

一. 进制的简介

  1. 常见进制

    • 二进制
    • 八进制
    • 十进制
    • 十六进制
    十进制数二进制数八进制数十六进制数
    0000000
    1000111
    2001022
    3001133
    4010044
    5010155
    6011066
    7011177
    81000108
    91001119
    10101012A
    11101113B
    12110014C
    13110115D
    14111016E
    15111117F
  2. 基数
    所谓基数就是在某种数中,允许选用基本数字符号的个数,如R进制的基数为R,能够使用的数字符号个数为R个,即0、1、2、3……R-1,每个位数满R进一。

  3. 权位
    一个数字符号在不同位时,它所代表的数值是不同的。每个数字符号所代表的数值等于该符号值乘以一个数与该数码所在位置有关的常数,这个常数就叫做位权。位权的大小是以基数为底,数字符号所在位置的序号为指数的整数次幂。
    性质:1,整数的最低位的权都是1
    2,进制数相邻的两位权的比值为R

二. 进制间的相互转化

  1. R进制转换为十进制权值展开法

    从左向右依次将这个进制的每一位数字符号值乘以该数码所在为值的位权,将所有求得的十进制值求和,所得即为该进制数转换为十进制数的数值。

  1. 十进制数转换为其它进制
  • 整数部分的转换
    十进制整数部分的转换规则是“除基取余法”,将十进制除以基数R,得到一个商和一个余数,再将商除以R,再次得到一个商和一个余数,重复此过程直到商为0为止。每次所得的余数就是该十进制数转换为R进制所得的数,其中以最后一次取得的余数为最高位,第一次取到的余数为最低位。

    例: 十进制13 转换 二进制数

将所得二进制数以最后一次取得的余数为最高位,第一次取到的余数为最低位依次排开
得13(D) = 1101(B)

void reverse_my(char *str);
//10进制转任意进制数(改进版加/**/为原版)
void myitoa(char *str, int n, int radix)
{
    int i = 0;
    
    const static char *numOf36 = { "0123456789ABCDEFGHIJKLMOPENRSTUVWXYZ" };
    while (n != 0)
    {
        int tmp = n % radix;
        n /= radix;
        /*if (tmp >= 10)
        {
            str[i++] = 'A' + tmp - 10;
        }
        else {
            str[i++] = '0' + tmp;
        }*/
        str[i++] = numOf36[tmp];
    }
    str[i] = '\0';
    /*for (int j = 0, k = i - 1; j < k; j++, k--)
    {
        char tmp = str[k];
        str[k] = str[j];
        str[j] = tmp;
    }*/
    reverse_my(str);
}

void reverse_my(char *str)
{
    char *low = str;
    char *high;
    for (high = str; *high != '\0'; high++);
    high--;
    char tmp;

    while (low <= high)
    {
        tmp = *low;
        *low = *high;
        *high = tmp;
        low++;
        high--;
    }
}
  • 小数部分的转换
    十进制小数部分的转换规则为“乘基取整法”。用十进制的小数部分乘以基数R,取走其乘积的整数部分之后,余下的小数部分在与R相乘。重复下去,直到余下的小数部分为0或者满足所要求的精度为止。每次所得的整数部分就是所求的R进制小数,将第一次所得整数位高位,最后一次所得整数为最低位。
> 将所得二进制第一次所得整数位高位,最后一次所得整数为最低位依次展开
>得0.875(D) = 0.111(B)
  1. 二进制与八进制、十六进制的转换
  • 二进制转换为八进制:
    从二进制数的小数点开始,分别向左向右以三位二进制数为一组,将每一组二进制数转换为一位八进制数。当小数部分的最后一组不够三位时,应在后面舔0补足。整数最前一组不够三位,应在前面舔0。
  • 二进制转换为十六进制:
    与二进制转换为八进制类似,以四位二进制数为一组,每组四位二进制数转换为一位十六进制数。。当小数部分的最后一组不够四位时,应在后面舔0补足。整数最前一组不够四位,应在前面舔0。
  • 八进制、十六进制转换为二进制
    分别将八进制(十六进制)每一个符号字符写成二进制的格式,即为二进制数。
  1. 任意进制之间的转行以代码实现

    思路:以10进制为中间进制将p进制转行为10进制再转换为q进制。

#include<stdio.h>
#include<ctype.h>
#include<string.h>
#include<stdlib.H >

//最大位数
#define MAX_DIGIT 10010

/*
    将当前c进制数转换为十进制数,
    所得10进制模p(所得的进制)得所求进制
*/
char Remainder(int *num,int len,int p,int c)
{
    int rem1 = 0;
    int rem2 = 0;
    
    for (int i = 0; i < len; i++)
    {
        rem1 = (num[i] + rem2 * c) % p;
        num[i] = (num[i] + rem2 * c) / p;
        rem2 = rem1;
    }
    return rem2;
}

int ctoi(int *num, char *str)
{
    int len1 = strlen(str);

    for (int i = 0; i < len1; i++)
    {
        if (isalnum(str[i]))
        {
            num[i] = str[i] - '0';
        }
        else if (isalpha(str[i]))
        {
            num[i] = iswlower(str[i]) - 'a' + 10;
        }
    }
    return len1;
}

int RevIntToChar(char *num,int  *num2,int len)
{
    int i;
    for (i = 0; i < len; i++)
    {
        if (num2[len-i-1] >= 10)
        {
            num[i] = num2[len-i-1] + 'A' -10;
        }
        else
        {
            num[i] = num2[len-i-1] + '0';
        }
    }
    num[i] = '\0';
    return len;
}

//思路
//字符型->整数c进制->倒序p进制->正序p进制
//  char -> int    ->   int  ->  char
void BinaryConversion(char *num, int pre, int cut)
{
    int  num1[MAX_DIGIT] = { 0 };
    int len_int = 0;

    int  num2[MAX_DIGIT] = { 0 };
    int len_rev = 0;

    len_int = ctoi(num1, num);

    while (true)
    {
        int flag = true;
        num2[len_rev++] = Remainder(num1, len_int, pre, cut);

        if (len_rev > MAX_DIGIT) EXIT_FAILURE; //最大位数超出限制停止程序

        for (int j = 0; j < len_int; j++)
        {
            if (num1[j] != 0)
            {
                flag = false;
                break;
            }
        }

        if (flag)
        {
            break;
        }
    }

    RevIntToChar(num, num2, len_rev);
}

int main()
{
    int pre=16;//下一个进制
    int cut=8;//当前进制

    char num[MAX_DIGIT] = "1234567123456";

    int len_str = strlen(num);

    if(len_str>MAX_DIGIT) EXIT_FAILURE; //最大位数超出限制停止程序

    BinaryConversion(num, pre, cut);

    printf("%s", num);

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值