0

We were assigned a task to convert octal numbers to binary and decimal. Smaller numbers works just fine but it then gives a different output at a higher input. Here is the code:

#include <stdio.h>

void main() {
  unsigned long n, g, ans = 1, r = 0, dec = 0, place = 1, bin = 0;
  printf("Conversion: Octal to decimal and binary.\n");
  printf("Enter number: ");
  scanf("%lu", &n);
  printf("%lu is ", n);

  for (g = n; g != 0; ans = ans * 8) {
    r = g % 10;
    dec = dec + r * ans;
    g = g / 10;
  }

  printf("%lu in Decimal Form. \n", dec);

  printf("%lu is ", n);
  for (; dec != 0; place = place * 10) {
    r = dec % 2;
    bin = bin + (r * place);
    dec = dec / 2;
  }
  printf("%lu in Binary Form.\n", bin);
}

We were only required to use limited data types and control structures. No arrays, strings, functions or such.

The input in our teacher's test case is 575360400 which must print an output of 101111101011110000100000000 in binary and 100000000 in decimal. But the output in binary is 14184298036271661312. I used unsigned long already and it just won't work.

I don't know how this is possible with the given restrictions and your comments and answers will be really much of a help.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
PABLO1403
  • 11
  • 4

1 Answers1

0

Smaller numbers works just fine but it then gives a different output at a higher input.

Overflow

Input "575360400" (base 8) converts to a 27-bit value. For place = place * 10 ... bin = bin + (r * place); to work, bin needs to be a 90-bit unsigned long. unsigned long is certainly 64-bit or less.

OP needs a new approach.


I'd start with reading the octal input with scanf("%lo", &n); and printing the decimal with printf("%lu\n", n);.

To print in binary, without arrays, functions, etc., consider a mask, first with the most significant bit, that is shifted right each iteration.

  bool significant_digit = false;

  // Form 0b1000...0000
  //                   0b1111... - 0b01111..
  unsigned long mask = ULONG_MAX - ULONG_MAX/2;

  while (mask) {
    bool bit = mask & n;
    if (bit || significant_digit || mask == 1) {
      significant_digit = true;
      printf("%d", bit);
    }
    mask >>= 1;
  }
  printf("\n", bit);
}

Better approaches exist. Yet with OP's artificial limitations: "No arrays, strings, functions or such.", I opted for something illustrative and simple.


Or wait until 2023

C2x expected to support printf("%lb\n", n);. Just ask the professor for an extension .

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • ```bool``` does not work on my compiler oh my god, lemme try a different one – PABLO1403 Dec 12 '21 at 07:40
  • @PABLO1403 "bool does not work on my compiler" --> What C compiler and version are you using? Be sure to add `#include `. Alternate: `int bit = !!(mask & n);`. – chux - Reinstate Monica Dec 12 '21 at 13:27
  • I used ```#include``` and it seems to identify ```bool``` already. But I am confused about some variables such as ```ULONG_MAX``` and ```bit``` – PABLO1403 Dec 13 '21 at 06:18
  • @PABLO1403 The _constant_ `ULONG_MAX` is defined in `` and is the maximum value for an object of type `unsigned long`. `bit` is a _binary digit_: a unit of data storage that may have one of two values. – chux - Reinstate Monica Dec 13 '21 at 09:57