为什么在我的二进制到十进制转换器程序中只有前 2 个输出是正确的?
Why are only the first 2 outputs correct in my binary to decimal converter programm?
我必须编写一个转换器,它从 numbers[]
获取字符串并将它们输出为小数。
我正在遍历大小和索引,然后将当前索引与其位置的幂相加,然后将其相加。比如:101 = 1^2 + 0^1 + 1^0
所以我目前坚持这个:
#include <stdio.h>
#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
int main() {
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"};
// Add here..
int strlen(char *str){
int len=0;
for(;str[len]!='[=10=]';len++){}
return len;
}
int sum = 0;
int length = sizeof(numbers) / sizeof(numbers[0]);
for( int i = 0; i < length; i++ ){
int size = strlen(numbers[i]);
for (int j = 0; j < size; j++) {
if(numbers[i][j] == '1'){
sum += 1 * pow(2,j-1);
}else{
sum += 0 * pow(2,j-1);
}
}
printf("%s to the base of 2 \nequals %d to the base of 10 \n\n",numbers[i], sum);
sum = 0;
}
return 0;
}
前两个循环的输出是正确的,即01001001 = 73和00101010 = 42。但是,一旦长度变大,我的输出就完全错误了;例如010100111001 = 1253 而不是 1337 和 011111110100101010010111 = 7645567 而不是 8342167.
sizeof(); // it will give you the size of datatype (in bytes), not the length of a string.
您必须改用字符串函数。
length = strlen(numbers[0]);
你的功能很糟糕,很复杂,而且使用 pow
。您不需要知道字符串的长度。
可以做得更简单:
unsigned long long bstrtoint(const char *str)
{
unsigned long long result = 0;
while(*str)
{
result *= 2;
result += *str++ == '1';
}
return result;
}
或对于任何基数(少于位数)
//bad digits considered as zeroes
static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUWXYZ";
unsigned long long strtoint(const char *str, unsigned base)
{
unsigned long long result = 0;
char *ppos;
while(*str)
{
result *= base;
result += (ppos = strchr(digits, toupper(*str++))) ? (ppos - digits < base) ? ppos - digits : 0 : 0;
}
return result;
}
示例:
printf("%llu\n", bstrtoint("1111000011110000"));
printf("%llu\n", strtoint("0001010110011010101111101111010101110110", 2));
printf("%llu\n", strtoint("1dr45Xvy4", 36)); // base 36 number
https://godbolt.org/z/bsG5rfTsb
如果您想使用您的程序布局并正确执行:
int main(void) // For strict compliance, you should add the "void" argument list
{
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101" };
unsigned long long sum = 0;
size_t length = sizeof(numbers) / sizeof(numbers[0]);
for (size_t i = 0; i < length; i++)
{
size_t size = strlen(numbers[i]); // strlen gives a "size_t" type
sum = 0;
for (size_t j = 0; j < size; j++)
{
sum *= 2;
if (numbers[i][j] == '1')
{
sum += 1;
}
}
printf("%s to the base of 2 \nequals %llu to the base of 10 \n\n", numbers[i], sum);
}
return 0;
}
但您不必将字符串整合两次 - strlen
根本不需要
int main(void) // For strict compliance, you should add the "void" argument list
{
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101" };
unsigned long long sum = 0;
size_t length = sizeof(numbers) / sizeof(numbers[0]);
for (size_t i = 0; i < length; i++)
{
sum = 0;
for (size_t j = 0; numbers[i][j] != 0; j++)
{
sum *= 2;
if (numbers[i][j] == '1')
{
sum += 1;
}
}
printf("%s to the base of 2 \nequals %llu to the base of 10 \n\n", numbers[i], sum);
}
return 0;
}
您的代码存在许多问题。首先,正如评论中指出的那样,您正在从左到右处理二进制数字,而您应该从右到左处理。
其次,在另一个函数中声明一个函数(就像您为 strlen
所做的那样)不是标准 C(尽管某些编译器可能允许这样做)。如果你真的不能使用标准的 strlen
函数(在 <string.h>
中提供),那么将你的定义移到 main
.
的主体之外(和之前)
第三,您不应该使用 pow
函数(它接受 returns double
值)进行整数运算。只需使用一个 运行 int
变量,并在每次内部 for
循环运行时将其乘以二。
第四,您的 "0001010110011010101111101111010101110110"
值将溢出大多数机器上的 int
类型(假设是 32 位),因此请尝试在必要时使用 long long int
(最有可能是 64 位) .
最后,无论 x
是什么,都没有必要将 0 * x
添加到任何内容,因此您可以取消 else
块。
这是一个工作版本(使用标准 strlen
):
#include <stdio.h>
#include <string.h> // For "strlen" - we don't need math.h if we don't use "pow".
int main(void) // For strict compliance, you should add the "void" argument list
{
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101" };
long long int sum = 0; // So we can use more than 32 bits!
size_t length = sizeof(numbers) / sizeof(numbers[0]);
for (size_t i = 0; i < length; i++) {
int size = (int)strlen(numbers[i]); // strlen gives a "size_t" type
long long int p = 1;
for (int j = size-1; j >= 0; j--) { // Start at the END of the string and work backwards!
if (numbers[i][j] == '1') {
sum += p;
}
// No point in adding zero times anything!
p *= 2; // Times by two each time through the loop
}
printf("%s to the base of 2 \nequals %lld to the base of 10 \n\n", numbers[i], sum);
sum = 0;
}
return 0;
}
我必须编写一个转换器,它从 numbers[]
获取字符串并将它们输出为小数。
我正在遍历大小和索引,然后将当前索引与其位置的幂相加,然后将其相加。比如:101 = 1^2 + 0^1 + 1^0
所以我目前坚持这个:
#include <stdio.h>
#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
int main() {
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"};
// Add here..
int strlen(char *str){
int len=0;
for(;str[len]!='[=10=]';len++){}
return len;
}
int sum = 0;
int length = sizeof(numbers) / sizeof(numbers[0]);
for( int i = 0; i < length; i++ ){
int size = strlen(numbers[i]);
for (int j = 0; j < size; j++) {
if(numbers[i][j] == '1'){
sum += 1 * pow(2,j-1);
}else{
sum += 0 * pow(2,j-1);
}
}
printf("%s to the base of 2 \nequals %d to the base of 10 \n\n",numbers[i], sum);
sum = 0;
}
return 0;
}
前两个循环的输出是正确的,即01001001 = 73和00101010 = 42。但是,一旦长度变大,我的输出就完全错误了;例如010100111001 = 1253 而不是 1337 和 011111110100101010010111 = 7645567 而不是 8342167.
sizeof(); // it will give you the size of datatype (in bytes), not the length of a string.
您必须改用字符串函数。
length = strlen(numbers[0]);
你的功能很糟糕,很复杂,而且使用 pow
。您不需要知道字符串的长度。
可以做得更简单:
unsigned long long bstrtoint(const char *str)
{
unsigned long long result = 0;
while(*str)
{
result *= 2;
result += *str++ == '1';
}
return result;
}
或对于任何基数(少于位数)
//bad digits considered as zeroes
static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUWXYZ";
unsigned long long strtoint(const char *str, unsigned base)
{
unsigned long long result = 0;
char *ppos;
while(*str)
{
result *= base;
result += (ppos = strchr(digits, toupper(*str++))) ? (ppos - digits < base) ? ppos - digits : 0 : 0;
}
return result;
}
示例:
printf("%llu\n", bstrtoint("1111000011110000"));
printf("%llu\n", strtoint("0001010110011010101111101111010101110110", 2));
printf("%llu\n", strtoint("1dr45Xvy4", 36)); // base 36 number
https://godbolt.org/z/bsG5rfTsb
如果您想使用您的程序布局并正确执行:
int main(void) // For strict compliance, you should add the "void" argument list
{
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101" };
unsigned long long sum = 0;
size_t length = sizeof(numbers) / sizeof(numbers[0]);
for (size_t i = 0; i < length; i++)
{
size_t size = strlen(numbers[i]); // strlen gives a "size_t" type
sum = 0;
for (size_t j = 0; j < size; j++)
{
sum *= 2;
if (numbers[i][j] == '1')
{
sum += 1;
}
}
printf("%s to the base of 2 \nequals %llu to the base of 10 \n\n", numbers[i], sum);
}
return 0;
}
但您不必将字符串整合两次 - strlen
根本不需要
int main(void) // For strict compliance, you should add the "void" argument list
{
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101" };
unsigned long long sum = 0;
size_t length = sizeof(numbers) / sizeof(numbers[0]);
for (size_t i = 0; i < length; i++)
{
sum = 0;
for (size_t j = 0; numbers[i][j] != 0; j++)
{
sum *= 2;
if (numbers[i][j] == '1')
{
sum += 1;
}
}
printf("%s to the base of 2 \nequals %llu to the base of 10 \n\n", numbers[i], sum);
}
return 0;
}
您的代码存在许多问题。首先,正如评论中指出的那样,您正在从左到右处理二进制数字,而您应该从右到左处理。
其次,在另一个函数中声明一个函数(就像您为 strlen
所做的那样)不是标准 C(尽管某些编译器可能允许这样做)。如果你真的不能使用标准的 strlen
函数(在 <string.h>
中提供),那么将你的定义移到 main
.
第三,您不应该使用 pow
函数(它接受 returns double
值)进行整数运算。只需使用一个 运行 int
变量,并在每次内部 for
循环运行时将其乘以二。
第四,您的 "0001010110011010101111101111010101110110"
值将溢出大多数机器上的 int
类型(假设是 32 位),因此请尝试在必要时使用 long long int
(最有可能是 64 位) .
最后,无论 x
是什么,都没有必要将 0 * x
添加到任何内容,因此您可以取消 else
块。
这是一个工作版本(使用标准 strlen
):
#include <stdio.h>
#include <string.h> // For "strlen" - we don't need math.h if we don't use "pow".
int main(void) // For strict compliance, you should add the "void" argument list
{
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101" };
long long int sum = 0; // So we can use more than 32 bits!
size_t length = sizeof(numbers) / sizeof(numbers[0]);
for (size_t i = 0; i < length; i++) {
int size = (int)strlen(numbers[i]); // strlen gives a "size_t" type
long long int p = 1;
for (int j = size-1; j >= 0; j--) { // Start at the END of the string and work backwards!
if (numbers[i][j] == '1') {
sum += p;
}
// No point in adding zero times anything!
p *= 2; // Times by two each time through the loop
}
printf("%s to the base of 2 \nequals %lld to the base of 10 \n\n", numbers[i], sum);
sum = 0;
}
return 0;
}