-1

I tried to convert a negative decimal number into a binary number and this code perfectly works on my computer, but the code doesn't work another computer.

I didn't get how it is possible. What is wrong in my code?

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

void decTobin(int dec, int s)
{
    int b[s], i = 0;

     while (dec >= 0 && i != s - 1) {
         b[i] = dec % 2;
         i++;
         dec /= 2;
     }

     int j = i;

     printf("%d", dec);

     for (j = i - 1; j >= 0; j--) {
         if (b[j] == NULL)
             b[j] = 0;

         printf("%d",b[j]);
     }
}

void ndecTobin(int dec, int s)
{
    int b[s], i = 0, a[s], decimal, decimalvalue = 0, g;

    while (dec >= 0 && i != s-1) {
        b[i] = dec % 2;
        i++;
        dec /= 2;
    }

    int j = i;

    printf("%d",dec);

    for (j = i - 1; j >= 0; j--) {
        if (b[j] == NULL)
            b[j] = 0;

        printf("%d",b[j]);
    }

    printf("\n");

    a[s - 1] = dec;

    for (j = s - 2; j >= 0; j--) {
        a[j] = b[j];
    }

    for (j = s - 1; j >= 0; j--) {
        if (a[j] == 0)
            a[j] = 1;
        else
            a[j] = 0;

        printf("%d",a[j]);
    }

    for (g = 0; g < s; g++) {
        decimalvalue = pow(2, g) * a[g];
        decimal += decimalvalue;
    }

    decimal = decimal + 1;
    printf("\n%d\n", decimal);
    decTobin(decimal, s);
}

int main()
{
    int a, b;

    printf("enter a number: ");
    scanf(" %d", &a);
    printf("enter the base: ");
    scanf("%d", &b);

    ndecTobin(a, b);
}
fuz
  • 88,405
  • 25
  • 200
  • 352
bendensin
  • 31
  • 1
  • 4
  • 2
    I hope you know what `"Meaningful names"` means?! – Rizier123 Dec 13 '14 at 15:51
  • 2
    I formatted the source code for you. Please try to post formatted source code next time, it's hard to answer a question that looks like somebody puked on the screen. – fuz Dec 13 '14 at 16:04
  • 2
    Please clarify "the code doesn't work another computer". Does it do nothing? Explode the monitor? Are you trying to run a Windows executable on a Mac? (Et cetera.) – Jongware Dec 13 '14 at 16:21

3 Answers3

3

decimal and int b[s] not initialized.

By not initializing decimal to 0, it might have the value of 0 on a machine one day and quite different results otherwise.

void decTobin(int dec, int s) {
  //  while loop does not set all `b`,but following for loop uses all `b`
  // int b[s], i = 0;  
  int b[s] = { 0 }; // or int b[s]; memset(b, 0, sizeof b);
  int i = 0; 
}

void ndecTobin(int dec, int s) {
  int b[s], i = 0, a[s], decimal, decimalvalue = 0, g;
  decimal = 0;
  ...
  decimal += decimalvalue;
}

Minor points:

1) if (b[j] == NULL) b[j] = 0; is strange. NULL is best used as a pointer, yet code is comparing b[j], an int to a pointer. Further, since NULL typically has the arithmetic value of 0, code looks like if (b[j] == 0) b[j] = 0;.

2) decTobin() is challenging to follow. It certainly is only meant for non-negative dec and s. Candidate simplification:

void decTobin(unsigned number, unsigned width) {
  int digit[width];
  for (unsigned i = width; i-- > 0; ) {
    digit[i] = number % 2;
    number /= 2;
  }

  printf("%u ", number);  // assume this is for debug

  for (unsigned i = 0; i<width; i++) {
    printf("%u", digit[i]);
  }
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
1

It looks like you are just printing the number as a binary representation. If so this version would work.

void print_binary(size_t n) {
   /* buffer large enough to hold number to print */
   unsigned buf[CHAR_BIT * sizeof n] = {0};
   unsigned i = 0;

   /* handle special case user calls with n = 0 */
   if(n == 0) {
      puts("0");
      return;
   }
   while(n) {
      buf[i++] = n % 2;
      n/= 2;
   }

   /* print buffer backwards for binary representation */
   do {
     printf("%u", buf[--i]);
   } while(i != 0);
}

If you don't like the buffer, you can also do it using recursion like this:

void using_recursion(size_t n)
{
   if (n > 1)
      using_recursion(n/2);

   printf("%u", n % 2);
}

Yet another way is to print evaluating most significant bits first. This however introduces issue of leading zeros which in code below are skipped.

void print_binary2(size_t n) {
   /* do not print leading zeros */
   int i = (sizeof(n) * 8)-1;
   while(i >= 0) {
      if((n >> i) & 1)
         break;
      --i;
   }

   for(; i >= 0; --i)
      printf("%u", (n >> i) & 1);
}
Angus Comber
  • 9,316
  • 14
  • 59
  • 107
  • @chux in case 1) do,while loop ends so will never get buf[-1]. 2) would work yes. It is unlikely that an int passed in current age would be more than 64 bits however. – Angus Comber Dec 13 '14 at 16:46
  • @chux Are you talking about a user calling the function with n = 0? – Angus Comber Dec 13 '14 at 16:57
0

Different OS/processor combinations may result in C compilers that store various kinds of numeric variables in different numbers of bytes. For instance, when I first learned C (Turbo C on a 80368, DOS 5) an int was two bytes, but now, with gcc on 64-bit Linux, my int is apparently four bytes. You need to include some way to account for the actual byte length of the variable type: unary operator sizeof(foo) (where foo is a type, in your case, int) returns an unsigned integer value you can use to ensure you do the right number of bit shifts.

Zeiss Ikon
  • 481
  • 4
  • 13