C中二进制转十进制出错
Converting binary to decimal goes wrong in C
我编写了这个程序,将二进制数传递给函数并打印该二进制数的十进制值。问题是,如果二进制数变大(比如 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);
}
P.S。我更改为此代码并且有效
#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");
}
您的代码过于复杂。切勿使用浮点数进行整数计算。
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"));
}
How can I change my program so that it prints the right decimal number even when the binary number gets big?
通过使您的 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
格式打印数字时
但在所有这些情况下,基数重要的表示是一串数字字符,而不是整数。
不编写接受整数的“二进制到...”函数有两个原因。一是,如您所见,它人为地且不必要地限制了您可以转换的数字的范围。但更大的原因是这让您的读者感到困惑,因为它 错误 。如果我看到函数调用
f(1001)
我心里想,“好吧,常数值一千零一正在传递给函数 f
。”在任何情况下我都不会想象它实际上是在尝试传递二进制数 9。
我编写了这个程序,将二进制数传递给函数并打印该二进制数的十进制值。问题是,如果二进制数变大(比如 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);
}
P.S。我更改为此代码并且有效
#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");
}
您的代码过于复杂。切勿使用浮点数进行整数计算。
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"));
}
How can I change my program so that it prints the right decimal number even when the binary number gets big?
通过使您的 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
格式打印数字时
但在所有这些情况下,基数重要的表示是一串数字字符,而不是整数。
不编写接受整数的“二进制到...”函数有两个原因。一是,如您所见,它人为地且不必要地限制了您可以转换的数字的范围。但更大的原因是这让您的读者感到困惑,因为它 错误 。如果我看到函数调用
f(1001)
我心里想,“好吧,常数值一千零一正在传递给函数 f
。”在任何情况下我都不会想象它实际上是在尝试传递二进制数 9。