C语言十进制转二进制

Decimal to Binary in C

我正在创建一个程序来加减 2 个数字。然后我必须把这个答案输出到不同的基地。

我的答案是十进制格式,类型为long double,如:

long double answer;
answer = numberOne + numberTwo;

我想将这个答案转换成二进制。现在我在我的程序中使用了前面的代码来执行此操作,但带有一个字符指针:

char * decimalBinary (char * decimalNumber) 
{

    bool zeroFront = true;
    int i;
    int z;
    int j = 0;
    int n = atoi(decimalNumber);
    char * binaryNum = malloc(32+1);
    binaryNum[32] = '[=11=]';

    int current_index=1;
    int end_index = strlen(decimalNumber)-1;

    //Error check for valid decimal input, needed error check for beginning of code
    while(current_index <= end_index)
    {
        if(decimalNumber[current_index] != '0' &&decimalNumber[current_index] != '1' &&decimalNumber[current_index] != '2' &&decimalNumber[current_index] != '3' &&decimalNumber[current_index] != '4' &&decimalNumber[current_index] != '5' &&dec[current_index] != '6' &&dec[current_index] != '7' &&decimalNumber[current_index] != '8' &&decimalNumber[current_index] != '9')
        {
            binaryNum[0] = -8;
            return binaryNum;
        }
        current_index++;
    }


    for (i = 31; i >= 0; i--) {
        z = n >> i;

        if (z & 1) 
        {
            binaryNum[j] = '1';
            j++;
            zeroFront = false;
        } 
       else if (!zeroFront) 
       {
            binaryNum[j] = '0';
            j++;
        }
    }

    binaryNum[j] = '[=11=]';

    return binaryNum;
}

我的首选解决方案是使用我的程序中已有的代码将我的答案转换为二进制格式,但正如您所看到的,参数存在冲突,我不确定该怎么做.

另一个有损于在我的程序中使用可重用代码的可能解决方案是创建一个不同的函数,将十进制转换为二进制,但接受 long double 类型的参数,这对我来说有点不清楚以及。

编辑: 我的答案不是 long double,而是类型 int

如果您真的想不加修改地重复使用您的函数,您可以将 answer 转换为十进制字符串并将该字符串传递给您的函数。

char stringAnswer[20];
sprintf(stringAnswer, "%d", answer);
printf("the binary answer is %s\n", decimalBinary(stringAnswer));

但更好的解决方案应该是将函数 decimalBinary 拆分为两个函数:第一个检查所有数字是否正确,第二个将 int 转换为二进制细绳。 然后你就可以用 answer 作为参数直接调用第二个函数。

与其使用幻数 32,不如让编译器推导出所需的大小,因为 int 并不总是 32 位。查看分配结果是个好习惯

#include <assert.h>
#include <stdlib.h>

#define INT_MAX_BIN_WIDTH (sizeof(int) * CHAR_BIT)
char * binaryNum = malloc(INT_MAX_BIN_WIDTH+1);
assert(binaryNum != NULL);
binaryNum[INT_MAX_BIN_WIDTH] = '[=10=]'; // null character

而不是检查每个数字,因为 '0''9' 必须是连续的:

// if(decimalNumber[current_index] != '0' &&decimalNumber[current_index] != '1' ...
if (decimalNumber[current_index] < '0' || decimalNumber[current_index] >= '9') ...
// or
if (!isdigit((unsigned char) decimalNumber[current_index])) ...

问题不涉及负数。最好声明它们不会发生或更好,让代码处理它们。


代码分配内存,但不释放它。考虑让更高级别的代码 allocate/free 并向 decimalBinary(char *dest, size_t size, const char *src) 提供所需的缓冲区。健壮的代码也会提供尺寸。

char *binaryNum = malloc(INT_MAX_BIN_WIDTH+1);
assert(binaryNum != NULL);
decimalBinary(binaryNum, INT_MAX_BIN_WIDTH+1, "123");
do_something(binaryNum);
free(binaryNum);

以下是不限于32位的解决方案。它不处理负数或内存分配 - 当然它应该为您的最终解决方案提供一些想法。

#include <stdio.h>
#include <string.h>

static void times10(char *binaryNumber, int carry) {
  size_t length = strlen(binaryNumber);
  size_t i = length;
  while (i > 0) {
    i--;
    int sum = (binaryNumber[i] - '0') * 10 + carry;
    binaryNumber[i] = sum % 2 + '0';
    carry = sum / 2;
  }
  while (carry) {
    memmove(&binaryNumber[1], &binaryNumber[0], ++length);
    binaryNumber[0] = carry % 2 + '0';
    carry /= 2;
  }
}

char *decimalBinary(char *binaryNumber, const char *decimalNumber) {
  strcpy(binaryNumber, "0");
  int ch;
  while ((ch = *decimalNumber++) >= '0' && (ch <= '9')) {
    times10(binaryNumber, ch - '0');
  }
  return binaryNumber;
}

int main(void) {
  char buf10[200];
  puts(decimalBinary(buf10, "123"));
  puts(decimalBinary(buf10, "123456"));
  puts(decimalBinary(buf10, "123456789012345678901234567890"));
  return 0;
}