在 C 中将二进制转换为十进制会出错
Posted
技术标签:
【中文标题】在 C 中将二进制转换为十进制会出错【英文标题】:Converting binary to decimal goes wrong in C 【发布时间】:2021-11-16 19:34:42 【问题描述】:我编写了这个程序,将二进制数传递给函数并打印该二进制数的十进制值。问题是如果二进制数变大(如 11 个数字),该函数会打印完全不同的东西。我现在尝试解决了几个小时,但没有任何效果。
所以我的问题是:如何更改我的程序,以便在二进制数变大的情况下打印正确的十进制数?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdint.h>
int int_log2_64(uint64_t x) return 63 ^ __builtin_clzll(x);
#define K(T) (((sizeof(#T) - 1) << 32) - T)
int digit_count(uint32_t x)
static uint64_t table[] =
K(0), K(0), K(0),
K(10), K(10), K(10), // 64
K(100), K(100), K(100), // 512
K(1000), K(1000), K(1000), // 4096
K(10000), K(10000), K(10000), // 32k
K(100000), K(100000), K(100000), // 256k
K(1000000), K(1000000), K(1000000), // 2048k
K(10000000), K(10000000), K(10000000), // 16M
K(100000000), K(100000000), K(100000000), // 128M
K(1000000000), K(1000000000), K(1000000000), // 1024M
K(1000000000), K(1000000000) // 4B
;
int lg2 = int_log2_64(x);
uint64_t n = (uint64_t)(x) + table[lg2];
return n >> 32;
void binaryToDecimal(long long int bin)
int l = digit_count(bin);
char str[l];
itoa(bin, str, 10);
float sum[l];
int x = l - 1;
float answer;
for (int i = 0; i < l; i++)
if (str[i] == '1')
sum[i] = pow(2, x);
x--;
for (int i = 0; i < l; i++)
answer = answer + sum[i];
printf("%.0f", answer);
int main()
long long int bin = 10101101101;
binaryToDecimal(bin);
附:我把代码改成了这个,它可以工作
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
void binaryToDecimal(char *bin)
int l = strlen(bin);
int x = l - 1;
float sum[l];
float answer = 0;
for (int i = 0; i < l; i++)
if (bin[i] == '1')
answer += pow(2, x);
else
sum[i] = 0;
x--;
printf("%.0f", answer);
int main()
binaryToDecimal("010101101101");
【问题讨论】:
你想让binaryToDecimal(100)
返回4
吗?您是否意识到您可以用 64 位表示的最大 int
是 18446744073709551615
(9223372036854775807
,如果已签名)?
另外,itoa()
(不在标准中,不在 POSIX 中)将int
作为第一个参数。您正在使用long long int
,它可能会被转换为警告。打开所有编译器警告。 注意警告。
最大无符号 32 位整数是 4294967295
,有符号 32 位整数是 2147483647
。
除了使用 itoa
和使用 float
的所有问题之外,char str[l]
太短了,因为它没有空间容纳空终止符(也没有空间容纳可能导致的减号将long long int
转换为int
时算术溢出)。另外,answer
还没有被初始化。
@hasan void binaryToDecimal(long long int bin)
。输入参数应该是一个字符串而不是long long int
【参考方案1】:
如何更改我的程序,以便在二进制数变大的情况下打印正确的十进制数?
通过将bin
变量设为字符串。
也就是说,你想要
void binaryToDecimal(const char *str)
...
然后你可以调用类似的东西
binaryToDecimal("101111000110000101001110");
在进行基本转换时,我认为使用整数变量作为输入总是错误的。如果我说
int x = 12;
不“x
是十进制整数”是真的。 x
是一个整数,句号——我只是碰巧使用了一个十进制常量来获取一个值。或者如果我说
int y = 0x7b;
那么说y
是十六进制就没有意义了——同样,y
只是一个整数。
表示整数的基数很重要:
在输入时,当我们使用scanf
和%d
、%o
或%x
格式从用户那里读取数字时
使用标准库atoi
或strtol
函数转换字符串时
在输出时,当我们使用printf
以%d
、%o
或%x
格式打印数字时
但在所有这些情况下,基数很重要的表示是一串数字字符,而不是整数。
不编写接受整数的“binary to ...”函数有两个原因。一个是,正如您所看到的,它人为且不必要地限制了您可以转换的数字范围。但更大的原因是这会让你的读者感到困惑,因为它只是错误。如果我看到一个函数调用
f(1001)
我想,“好吧,常量值 1001 正在传递给函数 f
。”在任何情况下,我都无法想象它实际上是在尝试传递二进制数 9。
【讨论】:
对于初级人类程序员来说,它是“十进制”(在这个阶段是“数字”的同义词)。理解会随着时间而来 谢谢,我把代码改成了几行就可以了!【参考方案2】:您的代码过于复杂。切勿使用浮点数进行整数计算。
unsigned binaryToDecimal(long long int bin)
unsigned answer = 0;
int shift = 0;
while(bin)
answer += (bin % 10) << shift++;
bin /= 10;
return answer;
int main()
long long int bin = 10101101101;
printf("%u\n", binaryToDecimal(bin));
https://godbolt.org/z/5E8Gv6oqf
或者使用字符串传递二进制数:
unsigned binaryToDecimal(char *str)
unsigned answer = 0;
while(*str)
answer <<= 1;
answer += *str++ == '1';
return answer;
int main()
printf("%u\n", binaryToDecimal("10101101101"));
https://godbolt.org/z/4vfnETY1f
【讨论】:
以上是关于在 C 中将二进制转换为十进制会出错的主要内容,如果未能解决你的问题,请参考以下文章