【C语言】十进制转换二进制

C/C++ 专栏收录该内容
37 篇文章 3 订阅

本题要求实现一个函数,将正整数n转换为二进制后输出。

  • 函数接口定义:
void dectobin(int n);
  • 函数dectobin应在一行中打印出二进制的n。建议用递归实现。

裁判测试程序样例:

#include <stdio.h>
void dectobin(int n);
int main()
{
    int n;
    scanf("%d", &n);
    dectobin(n);
    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:


10
521

输出样例:


1010
1000001001

[solution]

void dectobin(int n)
{
    int sum = 0;
    int y, x = 1; // y表示余数,x为叠加的系数
    while (n != 0)
    {
        y = n % 2;
        sum += x * y;
        x *= 10;
        n /= 2;
    }
    printf("%d", sum);
}

循环示意图:

n!=0
循环
y=n%2
sum+=x*y
sum
x*=10
n/=2

  • 进制转换网站安利:

在线进制转换

进制转换(技术方法)


1.短除法
十进制中的数位排列是这样的…… 万 千 百 十 个 十分 百分 千分…… R进制中的数位排列是这样的……R^4 R3R2 R^1 R^0
R^-1 R^-2 R^-3…… 可以看出相邻的数位间相差进制的一次方。
任何进制中,每个数都可以按位权展开成各个数位上的数字乘以对应数位的位权,再相加的形式,如:
十进制的123=1×100+2×10+3×1
十进制的9876=9×1000+8×100+7×10+6×1
问:为啥相应的数位是1000、100、10、1?为啥不是4、3、2、1?
答:十进制,满十进一,再满十再进一,因此要想进到第三位,得有10×10;第4位得有10×10×10
这样我们就知道了:
对10进制,从低位到高位,依次要乘以100,101,102,103……,也就是1、10、100、1000
对2进制,从低位到高位,依次要乘以20,21,22,23……,也就是1、2、4、8、……
下面我们开始转换进制(以十进制换成二进制为例):
原来十进制咱们的数位叫 千位、百位、十位……
现在二进制数位变成了八位、四位、二位……
模仿上面十进制按位权展开的方式,把二进制数1011按权展开: 1011=1×23+0×22+1×21+1×20=1×8+0×4+1×2+1×1=8+2+1=11
接下来我们进行十进制往二进制的转换:
比较小的数,直接通过拆分就可以转换回去
比如13,我们把数位摆好八位、四位、二位,不能写十六了,因为一旦“十六”那个数位上的符号是“1”,那就表示有1个16,即便后面数位上的符号全部是“0”,把这个二进制数按权位展开后,在按照十进制的运算规律计算,得到的数也大于13了。那最多就只能包含“八”这个数位。 13-8=5,5当中有4,5-4=1
好啦,我们知道13=18+14+02+11 把“1”、“1”、“0”“1”这几个符号放到数位上去:
八位、四位、二位、一位
1 1 0 1
于是十进制数13=二进制数1101
2.递归原理<“乘基取整法”>
1)一个十进制数321的末尾是1,意味着一定是……+1,省略号部分一定是10的倍数,所以一个十进制数末尾是1意味着十进制数除以进制10一定余1。所以第一次除以10之后的余数,应该放在十进制的最后一个数位“个位”,也就是说个位上的符号是1。
类比,一个二进制数111(注意,数值不等于上面十进制的111)末尾是1,意味着一定是……+1,前面的省略号部分都是2的倍数。所以一个二进制数末尾是1,意味着它对应的十进制数除以进制2一定余1。所以第一次除以2之后的余数,应该放在二进制的最后一个数位“一位”,也就是说一位上的符号是1。
2)如果一个十进制数321“十位”是2,我们希望把它转换为(1)的情况。那么我们把这个十进制数的末尾抹掉,也就是减去“个位”上的1,再除以进制10,得到32。这样原来“十位”上的“2”就掉到了“个位”上。再把32做(1)的处理。
类比,如果一个二进制数111“二位”是1,我们希望把它转换为(1)的情况,那么我们把这个二进制数的末尾抹掉,也就是减去“一位”上的1,再除以进制2,得到11。这样原来“二位”上的“1”就掉到了“一位”上。再把11做(1)的处理。
总结:其实这个过程就是把各个数位上的符号求出来的过程。
现在你应该可以回答以下问题了:为什么短除法可以实现进制的转换呢?为什么每次要除以进制呢?为什么要把余数倒着排列呢?
R进制转换成十进制就是按权位展开,把展开式放到十进制下,再按照“十进制”的运算规律计算。因为是十进制,所以就允许使用2、3、4、5、6、7、8、9了。所以2的n次方就不用写成指数,而可以用另外的八个符号来表示了。
十进制—>二进制
对于整数部分,用被除数反复除以2,除第一次外,每次除以2均取前一次商的整数部分作被除数并依次记下每次的余数。另外,所得到的商的最后一位余数是所求二进制数的最高位。


递归解法

void dectobin(int n)
{
    if (n == 0)
        printf("0");
    else if (n == 1)
        printf("1");
    else
    {
        dectobin(n / 2); //利用二进制的原理
        printf("%d", n % 2);
    }
}

不用函数,采用数组的方式

  • 【思路】将余数存放在数组中,倒序输出

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
    int i = 0, y, n, l = 0; // l记数组长度;
    int str[1000];
    printf("请输入一个数字: \n");
    scanf("%d", &n);
    if (n == 0)
    {
        printf("输出结果: \n");
        printf("0\n");
    }
    else
    {
        while (n != 0)
        {
            str[i] = n % 2;
            n /= 2;
            l++;
            i++;
        }
        printf("输出结果: \n");
        for (i = l - 1; i >= 0; i--)
            printf("%d", str[i]);
        printf("\n");
    }
    return 0;
}

  • 进一步的数值转换
  • 十进制转任意进制:

AC

#include <bits/stdc++.h>
using namespace std;
void convto(char *s, int n, int b)
{
    char bit[] = {"0123456789ABCDEF"};
    int len;
    if (n == 0)
    {
        strcpy(s, " ");
        return;
    }
    convto(s, n / b, b);
    len = strlen(s);
    s[len] = bit[n % b];
    s[len + 1] = '\0';
}
int main()
{
    char s[80];
    int i, base, old;
    cout << "请输入十进制数:" << endl;
    cin >> old;
    cout << "请输入转换的进制:" << endl;
    cin >> base;
    convto(s, old, base);
    cout << "转制后:" << endl;
    cout << s << endl;
    system("pause");
    return 0;
}

or

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
//整数幂运算函数
int int_pow(int x, int y)
{
    int i, result = 1;
    for (i = 1; i <= y; i++)
    {
        result *= x;
    }
    return result;
}
//将十进制数转换为任意进制
//参数 dnum 为十进制数,参数 jz 为目标进制
void dtox(int dnum, int jz)
{
    char xnum[100];
    int i = 0, j = 0;
    while (dnum >= jz)
    {
        if (dnum % jz <= 9)
            xnum[j++] = dnum % jz + 48;
        else
            xnum[j++] = dnum % jz - 10 + 'A';
        dnum /= jz;
    }
    if (dnum <= 9)
        xnum[j] = dnum + '0';
    else
        xnum[j] = dnum - 10 + 'A';
    for (i = j; i >= 0; i--)
    {
        cout << xnum[i];
    }
}

//将输入的数转换为十进制
//参数 num 是一个数组,保存输入的字符串,参数 jz 为源数据的进制
int xtod(char num[], int jz)
{
    int dnum = 0, i, n = 0, b;
    for (i = 0;; i++)
    {
        if (num[i] == '\0')
            break;
        else
            n++;
    }
    for (i = n - 1; i >= 0; i--)
    {
        if (num[n - i - 1] >= 'a')
            b = num[n - i - 1] - 'a' + 10;
        else if (num[n - i - 1] >= 'A')
            b = num[n - i - 1] - 'A' + 10;
        else
            b = num[n - i - 1] - '0';
        dnum += b * int_pow(jz, 1);
    }
    return dnum;
}
//主函数
int main()
{
    char num[100];
    int jz1, jz2;
    printf("输入要转换的数:");
    scanf("%s", num);
    printf("输入数的进制: ");
    scanf("%d", &jz1);
    printf("要转换的进制:");
    scanf("%d", &jz2);
    dtox(xtod(num, jz1), jz2);
    getchar();
    return 0;
}
  • 4
    点赞
  • 0
    评论
  • 14
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:我行我“速” 设计师:Amelia_0503 返回首页

打赏作者

小白兔奶糖ovo

蟹蟹

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值