【问题标题】:Decimal to Binary in CC中的十进制到二进制
【发布时间】:2015-09-22 18:41:16
【问题描述】:

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

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

long double answer;
answer = numberOne + numberTwo;

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

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] = '\0';

    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] = '\0';

    return binaryNum;
}

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

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

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

【问题讨论】:

  • long double 转换为二进制与将int 转换为二进制有很大不同(这就是您的代码所做的)。你确定这是你想要的吗?将 1.5 转换为二进制格式,您期望得到什么结果?
  • 是的,我相信我应该把 long double 改成 int
  • 您的answer 是系统用来表示其类型的任何格式。无论该类型是int 还是long double,其格式都不太可能很好地表征为“十进制”。
  • 您知道long double 是浮点格式吗?您将不得不处理相当大范围的值(可能需要添加一些“E+exp”后缀)和小数部分。
  • if(decimalNumber[current_index] != '0' &amp;&amp;decimalNumber[current_index] != '1' … '9') 行应该是if (!isdigit(decimalNumber[current_index]])),可以说是转换为(unsigned char) 作为参数。如果你必须像这样多次写出几乎相同的东西,你应该培养一种错误的感觉——并找到一种避免重复自己的方法。 The Pragmatic Programmer 支持的原则之一是 DRY:不要重复自己。

标签: c pointers binary type-conversion decimal


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    与其使用幻数 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] = '\0'; // 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])) ...
    

    问题不解决负数。最好声明它们不会发生,或者更好的是让代码处理它们。


    代码分配内存,但不释放它。考虑让更高级别的代码分配/释放并将所需的缓冲区提供给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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-23
      • 2014-04-19
      • 2019-04-09
      • 2017-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多