C语言进制转换专题

目录

十进制转换成r进制

八、十六进制转二进制

二进制转八、十六进制 

 //将十进制数转化为二进制数并打印出其中1的个数

n = n & ( n - 1 ) 的奇妙运用

//获取一个二进制序列中的偶数位和奇数位,分别打印出二进制序列

//两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同


此篇博客旨在讲解C语言中进制转换问题,并且搭配一些小练习。

当然了,在开始做题之前,必备的知识是不可少的,赶快来看看进制之间是如何转换的吧~ 

十进制转换成r进制

十进制:D;二进制:B;八进制:O;十六进制:H

整数部分:除以r取余,即将十进制整数不断除以r取余数,直至商为0,余数从右向左排列,首次取得的余数在最右;

小数部分:乘以r取整,即将十进制小数不断乘以r取整数,直至小数部分为0或达到所要求的精度为止,所得整数从小数点自左向右排列,首次取得的整数在最左。

下面用图文来演示一下将十进制数123.456转化为二进制: 

结果为1111011.011(B)小数点后几位数根据精度来定,不一定能够达到0,这里因为十进制取了小数点后三位,所以二进制也取后三位。

八、十六进制转二进制

一位八进制数对应三位二进制数;

一位十六进制数对应四位二进制数。

简单来说,就是将八进制和十六进制数的每一位拆开来看,分别用二进制表示即可。

下面我们同样用图文来演示一下:

 

二进制转八、十六进制 

这就相当于上面转换的逆运算,道理是一样的哈~

整数部分:从右向左按三(四)位进行分组,不足补零;

小数部分:从左向右按三(四)位进行分组,不足补零。

注意方向(相当于都从小数点出发),可不要记错了哦!

 //将十进制数转化为二进制数并打印出其中1的个数

法一:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	printf("请输入一个十进制数:");
	int n = 0;
	int length = 0;//用length来装二进制数的个数
	int arr[20];//定义一个数组来装余二得到的余数
	scanf("%d", &n);
	while ( n/2 )
	{
		arr[length] = n % 2;//存入数组中的是倒序的二进制序列
		length++;
		n = n / 2;
	}
	arr[length] = n % 2;//存储最后一个余数(当n/2==0时跳出循环,此时最后一位余数还未存储)
	int i = 0;          //此时length是最后一个数的下标
	printf("转为二进制为:");
	for (i = length ; i >= 0; i--)//将余数从下往上输出
	{
		printf("%d", arr[i]);
	}
	printf("\n");
	int count = 0;
	for (i = 0; i <= length; i++)//注意length是下标,所以要 <=
	{
		if (arr[i] == 1)
		{
			count++;
		}
	}
	printf("其中有%d个数字1", count);
	return 0;
}

 

法二:如果只要统计二进制中1的个数,可以简洁地这样写:

法三:来个高级点的,运用我们学过的操作符 & 和 >> 也可完成 :

 当然是有点小绕,不过问题不大。

int main()
{
	printf("请输入一个数:");
	int n = 0;
	scanf("%d", &n);//假设n为8——100
	int i = 0;
	int count = 0;
	for (i = 0; i < 32; i++)
	{
		if ((n >> i) & 1)//将二进制中的每一位逐个与1按位与&,这一位是1得到1,这一位是0得到0
		{                // n>>i --- 100 --> 010 --> 001    
			count++;     //  1   --- 001 --> 001 --> 001
		}                //  &   --- 000 --> 000 --> 001
	}                                             //所以8的二进制只有一个1
	printf("%d\n", count);
	return 0;
}

n = n & ( n - 1 ) 的奇妙运用

法四:最玄幻的操作了,效率也是最高的,如果你掌握了,可以向其他人装B了(bushi。

这也是谷歌面试题中的思路,还是很重要滴~

重点:n = n & ( n - 1 )

int main()
{
	printf("请输入一个数:");
	int n = 0;
	int count = 0;
	scanf("%d", &n);
	while (n)
	{
		n = n & (n - 1);
		count++;
	}
	printf("%d", count);
	return 0;
}

结果也照样能跑起来哦。 

再来看看这个公式还有哪些应用,如果让你写一个程序判断一个数是不是2的k次方,你会怎么做?是哼哧哼哧写上几十行代码,然后再忙不迭地改错?No no no,用这个公式几行代码就能搞定:

int main()
{
	printf("请输入一个数:");
	int n = 0;
	scanf("%d", &n);
	if ((n & (n - 1)) == 0)//注意这里的关系运算符 == 的优先级高于位运算符 & ,所以要加( ),否则结果全是No
	{
		printf("Yes\n");
	}
	else
	{
		printf("No\n");
	}
	return 0;
}

//获取一个二进制序列中的偶数位和奇数位,分别打印出二进制序列

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{
	printf("请输入一个十进制数:");
	int n = 0;
	int length = 0;
	int arr[20];
	scanf("%d", &n);
	while (n / 2)
	{
		arr[length] = n % 2;
		length++;
		n = n / 2;
	}
	arr[length] = n % 2;
	int i = 0;
	printf("其二进制为:");
	for (i = length; i >= 0; i--)
	{
		printf("%d", arr[i]);//一直到这里都与上面一题完全相同
	}
	printf("\n");//换行
	printf("奇数序列为:");
	for (i = length; i >= 0; i--)
	{
		if (i % 2 == 0)//打印奇数序列
		{
			printf("%d", arr[i]);
		}
	}
	printf("\n");//换行
	printf("偶数序列为:");
	for (i = length; i >= 0; i--)
	{
		if (i % 2 == 1)//打印偶数序列
		{
			printf("%d", arr[i]);
		}
	}
	printf("\n");
	return 0;
}

我们同样可以用上一题的&与>>来实现,代码会简洁不少:

int main()
{
	printf("请输入一个数:");
	int n = 0;
	scanf("%d", &n);
	int i = 0;
	printf("偶数位:");
	for (i = 30; i >= 0; i -= 2)
	{
		printf("%d ", (n >> i) & 1);
	}
	printf("\n");
	printf("奇数位:");
	for (i = 31; i >= 0; i -= 2)
	{
		printf("%d ", (n >> i) & 1);
	}
	return 0;
}

//两个int(32位)整数m和n的二进制表达中,有多少个位(bit)不同

 emmm……这可咋整??嘿嘿,如果能巧妙运用按位异或^这个操作符,题目就简单了~

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	int num1 = 0;
	int num2 = 0;
	int m = 0;
	int length = 0;//作为数组下标
	int arr[20];//定义一个数组放m的二进制序列
	printf("请输入两个数:");
	scanf("%d %d", &num1, &num2);
	m = num1 ^ num2;//按位异或后0与0为0,1与1为1,只有0与1时才为1
	while (m / 2)   //相当于bit位不同时为1(神奇~)
	{
		arr[length] = m % 2;//虽然这里存放的二进制位全是反向的,但不影响计数就行
		m = m / 2;//只有这个地方改变了m的值
		length++;
	}
	arr[length] = m % 2;//放入最后一个二进制数
	int i = 0;
	int count = 0;//作为计数器,记录有几个1
	for (i = 0; i <= length; i++)//
	{
		if (arr[i] == 1)
		{
			count++;
		}
	}
	printf("二进制码不同位的个数为:%d\n", count);
	return 0;
}

That's all ~ 创作不易,如果内容对你们有帮助,麻烦一键三连哦!如果发现什么Bug,也欢迎评论区里指正哦!菜菜先在这里谢过大家啦~

  • 16
    点赞
  • 83
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值