二进制大数转化十进制

/*计算二进制数转化为十进制数的结果*/

样例输入:

1111111

1111111111111111111111111111111111111111

样例输出:

127

1099511627775

这里使用了预处理,计算起来方便,直观。

 1 #include<stdio.h>
 2 #include<string.h>
 3 int main()
 4 {
 5     int s[110][110]={1};int p,q;
 6     for(p=1;p<=100;p++){
 7         int c=0;
 8         for(q=0;q<=p;q++)
 9         {int w=2*s[p-1][q]+c;
10         s[p][q]=w%10;
11         c=w/10;
12         }
13     }
14     char a[110]={0};
15     while(~scanf("%s",a))
16     {
17         int b[110]={0},i,j;int m=(int)strlen(a);
18         for(i=0,j=m-1;i<=j;i++,j--)
19         {int x=a[i]-'0';a[i]=a[j]-'0';a[j]=x;}
20         for(i=0;i<=m;i++)
21             if(a[i]){int r=0;
22                 for(int j=0;j<=i+1;j++){
23                     int y=b[j]+s[i][j]+r;
24                     b[j]=y%10;
25                     r=y/10;
26                 }
27             }
28         for(i=100;!b[i];i--);
29         for(j=i;j>=0;j--)printf("%d",b[j]);printf("\n");
30     }
31     return 0;
32 }

 

转载于:https://www.cnblogs.com/gj-Acit/archive/2012/12/29/2838437.html

<think>嗯,用户想了解如何用C语言将二进制换为十进制。我需要先回顾一下换的原理。二进制数每一位的权值是2的幂次方,从右往左,从0开始递增。例如,二进制数1101等于1*2^3 + 1*2^2 + 0*2^1 + 1*2^0,也就是13。 接下来,我得考虑如何在C代码中实现这个换。用户可能输入的是一个字符串形式的二进制数,比如"1010",或者是一个整数。不过,用字符串处理可能更直接,因为可以逐位读取每个字符,尤其是处理较长的二进制数时。 首先,需要读取用户的输入,确保输入的是有效的二进制数,即只包含0和1。这一步可能需要验证输入的每个字符,如果有非法字符就报错或者提示重新输入。 然后,处理输入的每一位。从左到右或者从右到左遍历,但考虑到权值的计算,从左到右的话,每处理一位,当前的十进制值可以乘以2再加上当前位的值。例如,初始值为0,处理第一位1,变成0*2+1=1;第二位0,变成1*2+0=2;第三位1,变成2*2+1=5;第四位0,变成5*2+0=10。这样,字符串"1010"就变成了十进制的10。 或者,也可以从右到左处理,每一位乘以2的相应次方,然后累加。但这样可能需要计算字符串长度,确定每一位的位置,然后从高位到低位循环。例如,对于"1010",长度是4,最高位是第3位(索引从0开始),然后每一位的值乘以2^(3 - i),其中i是当前索引。这种方法可能需要更多的计算,尤其是当二进制数很长的时候,计算幂次方可能会影响效率。 比较这两种方法,第一种方法更高效,因为不需要计算指数,只需要累积乘以2。所以应该采用第一种方法。 接下来,代码的结构概是这样的:读取字符串,验证每个字符是否是0或1,然后遍历字符串,使用累积的方法计算结果。 比如,用户输入"1101",初始化十进制数为0,然后循环每个字符: 0 → 0*2 + 1 = 1 1 → 1*2 + 1 = 3 0 → 3*2 + 0 = 6 1 → 6*2 +1 =13 这样就得到了正确的结果。 然后需要考虑输入的长度,可能用循环来处理每个字符,直到遇到字符串结束符'\0'。同时,处理可能的错误输入,比如包含非0或1的字符。 另外,如果用户输入的是整数类型的二进制数,比如输入101,那其实是十进制的101,处理起来不太方便,容易混淆。所以还是建议用字符串处理更准确。 可能的代码步骤: 1. 定义一个字符数组来存储输入的二进制字符串。 2. 使用scanf或者gets(但gets不安全,建议用fgets)来读取输入。 3. 遍历字符串中的每个字符,检查是否是'0'或'1',如果有其他字符则报错。 4. 初始化十进制数为0。 5. 对于每个有效字符,执行decimal = decimal * 2 + (current_char - '0')。 6. 最后输出十进制数。 现在,把这些步骤转化为C代码。同时要注意字符串的长度,防止溢出。 另外,可能需要处理前导零的情况,不过这在换过程中不会有影响,因为算法本身会处理。 测试用例,比如输入"1101",输出13;输入"1000",输出8;输入"0",输出0;输入"1",输出1。 可能的错误处理,比如输入中含有'2'或者字母,应该提示用户输入错误。 综上,代码的体框架应该是这样的: #include <stdio.h> #include <string.h> int main() { char binary[100]; printf("请输入一个二进制数:"); scanf("%s", binary); int decimal = 0; for (int i = 0; i < strlen(binary); i++) { if (binary[i] != '0' && binary[i] != '1') { printf("输入错误,必须为0或1\n"); return 1; } decimal = decimal * 2 + (binary[i] - '0'); } printf("十进制数为:%d\n", decimal); return 0; } 但这里有个问题,strlen每次循环都会调用,可能影响效率,可以预先计算长度。或者改用指针逐个字符处理直到遇到'\0'。 优化后的循环: int length = strlen(binary); for (int i = 0; i < length; i++) { ... } 或者用指针: char *p = binary; while (*p) { if (*p != '0' && *p != '1') { ... } decimal = decimal * 2 + (*p - '0'); p++; } 这样可能更高效。 另外,输入的长度是否超过数组的小,这里没有处理,但作为示例代码可能可以忽略,实际应用中需要考虑缓冲区溢出。 总结,用户需要的是一个简单直接的C代码示例,将二进制字符串换为十进制数,并处理可能的错误输入。需要逐步解释代码的逻辑,并说明每一步的作用,这样用户能理解实现的过程。</think>二进制十进制的核心原理是:每位数字乘以其对应的权值(2的幂次),再将所有位的计算结果相加。以下为分步实现说明和示例代码: ### 方法原理 $$ decimal = \sum_{i=0}^{n} (bit_i \times 2^{n-i-1}) $$ 其中 $bit_i$ 表示二进制数的第 $i$ 位(从左到右,从0开始计数)。 ### 代码实现 ```c #include <stdio.h> #include <string.h> int main() { char binary[100]; printf("请输入二进制数:"); scanf("%s", binary); // 获取用户输入 int decimal = 0; for (int i = 0; i < strlen(binary); i++) { // 遍历每一位 if (binary[i] != '0' && binary[i] != '1') { // 校验合法性 printf("错误:输入包含非二进制字符!\n"); return 1; } decimal = decimal * 2 + (binary[i] - '0'); // 核心计算公式 } printf("十进制结果:%d\n", decimal); return 0; } ``` ### 关键步骤说明 1. **输入验证**:通过 `if (binary[i] != '0' && binary[i] != '1')` 确保输入仅含 `0` 和 `1` 2. **逐位计算**:从最高位开始,每次将当前结果左移一位(等价于 `decimal * 2`),然后加上当前位的值 - 例如 `"1101"` 的计算过程: ``` 初始值 0 → 0*2+1=1 → 1*2+1=3 → 3*2+0=6 → 6*2+1=13 ``` ### 扩展优化方向 1. **性能优化**:预先计算 `strlen(binary)` 避免循环重复调用 2. **大数支持**:改用 `long long` 类型存储结果 3. **安全输入**:使用 `fgets` 替代 `scanf` 防止缓冲区溢出 ### 测试案例 | 输入 | 输出 | |----------|------| | `1010` | 10 | | `1111` | 15 | | `100000` | 32 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值