目录
前言:
在用C语言解决前,先复习一下进制的转化,知识点。这里就不过多解释了。
法一: 运用数学函数
二进制转十进制思路
因为二进制数字是非0即1,所以第一步是判断输入的数字是否为0与1组成
步骤一:判断函数
int panduan(char binary[])
{
for (int i = 0; binary[i] != '\0'; i++ )
{
if (binary[i] != '0' && binary[i] != '1')
{
return 0; // 无效
}
}
return 1; // 有效
}
步骤二:转化
源码:
可以将判断与储存相结合 判断在对应位权的0与1.
int zuanhua_shi(char num[])
{
int shi = 0;
int length = strlen(num);for (int i = 0; i < length; i++)
{
if (num[i] == '1')
{
// 计算2的(长度-1-i)次幂
shi += pow(2, length - 1 - i);
}
}return shi;
}
工作原理示例
二进制数 "1101"
的转换过程:
-
第0位(最右边):
1
→1 × 2⁰ = 1
-
第1位:
0
→0 × 2¹ = 0
-
第2位:
1
→1 × 2² = 4
-
第3位:
1
→1 × 2³ = 8
-
总和:
1 + 0 + 4 + 8 = 13
完整代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <math.h>
int panduan(char binary[])
{
for (int i = 0; binary[i] != '\0'; i++ )
{
if (binary[i] != '0' && binary[i] != '1')
{
return 0; // 无效
}
}
return 1; // 有效
}
int zuanhua1(char num[])
{
int shi = 0;
int length = strlen(num);
for (int i = 0; i < length; i++)
{
if (num[i] == '1')
{
// 计算2的(长度-1-i)次幂
shi += pow(2, length - 1 - i);
}
}
return shi;
}
int main()
{
char num[33]; // 最多32位二进制数 + 结束符
printf("请输入一个二进制数: ");
scanf("%32s", num); // 限制输入长度防止溢出
// 验证输入
if (!panduan(num))
{
printf("错误:输入的不是有效的二进制数!\n");
return 1;
}
printf("二进制数转换为十进制的结果 % d\n", zuanhua1(num));
return 0;
}
法二:运用位运算
判断函数同上
基础知识
在编写代码前先了解下运运算的符号,有了基础才能更好的理解
1. 按位与(&)
按位与操作符对两个操作数的每一位执行逻辑与操作。只有两个对应位都为1时,结果位才为1。
示例:
unsigned int a = 5; // 二进制: 0101 unsigned int b = 3; // 二进制: 0011 unsigned int c = a & b; // 结果: 0001 -> 1
2. 按位或(|)
按位或操作符对两个操作数的每一位执行逻辑或操作。只要两个对应位中有一个为1,结果位就为1。
示例:
unsigned int a = 5; // 二进制: 0101 unsigned int b = 3; // 二进制: 0011 unsigned int c = a | b; // 结果: 0111 -> 7
3. 按位异或(^)
按位异或操作符对两个操作数的每一位执行逻辑异或操作。如果两个对应位相同则结果位为0,不同则结果为1。
示例:
unsigned int a = 5; // 二进制: 0101 unsigned int b = 3; // 二进制: 0011 unsigned int c = a ^ b; // 结果: 0110 -> 6
4. 按位取反(~)
按位取反操作符是一个单目运算符,它对操作数的每一位执行取反操作,即0变成1,1变成0。
示例:
unsigned int a = 5; // 二进制: 0101 unsigned int b = ~a; //1010 // 结果: 11111111111111111111111111111010(假设是32位系统,结果为4294967290)
5. 左移(<<)
左移操作符将操作数的二进制位全部左移指定的位数,高位丢弃,低位补0。
示例:
unsigned int a = 5; // 二进制: 0101 红色的丢掉 unsigned int b = a << 1; // 结果: 1010 -> 10
6. 右移(>>)
右移操作符将操作数的二进制位全部右移指定的位数。对于无符号数,高位补0;
对于有符号数,高位补符号位(算术右移)或补0(逻辑右移,取决于编译器)。
示例:
unsigned int a = 5; // 二进制: 0101 unsigned int b = a >> 1; // 结果: 0010 -> 2
右移一位相当于除以2(向下取整),右移n位相当于除以2的n次方。
注意事项
-
位运算符只能用于整数类型(char, int, long等),不能用于浮点数。
-
左移和右移操作要注意位移的位数不能超过或等于操作数的位数,否则行为未定义。
-
对于有符号数的右移,不同编译器可能采用算术右移或逻辑右移,因此可移植性代码应避免对有符号数进行右移操作。
转化函数
int zhuanhua2(char binary[])
{
int decimal = 0;
int length = strlen(binary);
for (int i = 0; i < length; i++)
{
// 左移一位相当于乘以2
decimal = decimal << 1;
if (binary[i] == '1')
{
decimal += 1;
}
}
return decimal;
}
详细解释:
例如 binary[]=1101
length=4
decimal
= 0(二进制:0000)第一次 i=0
binary[0]=1
经过 if (binary[i] == '1')
{
decimal += 1;
}所以decimal=1(二进制0001)
第二次 i=1
binary[1]=1
同上
所以decimal = decimal << 1; // 1 << 1 = 2 (二进制0010)
+1
decimal
= 3
对比
对于"1101":
传统公式:1×2³ + 1×2² + 0×2¹ + 1×2⁰ = 8 + 4 + 0 + 1 = 13
我们的算法:
处理'1':0×2 + 1 = 1
处理'1':1×2 + 1 = 3
处理'0':3×2 + 0 = 6
处理'1':6×2 + 1 = 13
法三:简单乘法
原理同上只不过是上一个方法是运用移位符,效果也就是乘二
那么 有同学可能已经猜到了把
那就是直接乘以2
如下
int binaryToDecimal_simple(char binary[]) {
int decimal = 0;
int length = strlen(binary);
for (int i = 0; i < length; i++) {
decimal = decimal * 2; // 相当于左移一位
if (binary[i] == '1') {
decimal += 1;
}
}
return decimal;
}
这个就不再详解一二了。
总结:
二进制的转化方法有很多种 希望大家可以理解掌握,
同理那么十六进制 8进制的转化方法也可以自己编写了。
在下一章或为大家提供。。。