3

I tried to convert a base 10 number to base 6 in C, but my code didn't pass 2 hidden test cases.

I can't find any logical error in it.

Could you?

//convert base 10 to base 6

#include<stdio.h>
int main()
{
   int num, rem = 0, i = 1, res = 0;
   scanf("%d", &num);
   while(num!=0)
   {
       rem = num%6;
       res = (rem*i)+res;
       num = num/6;
       i = i*10;
   }
   printf("%d",res);

}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Viky
  • 63
  • 2
  • 7
  • 2
    No check for overflow. – PaulMcKenzie Jul 18 '19 at 06:23
  • 2
    Is this a C or C++ question? What's the spec against which this is tested? – ikegami Jul 18 '19 at 06:25
  • Show the challenge or the homework assignment please. With some experience (StackOverflow users will provide that) usually you can read the testcases from there. – Yunnosch Jul 18 '19 at 06:26
  • @ikegam this is C question – Viky Jul 18 '19 at 06:30
  • `123456789` will fail miserably if `sizeof(int)` is 4. – PaulMcKenzie Jul 18 '19 at 06:31
  • @SanderDeDycker I did it pal, but i can't find anything went wrong. – Viky Jul 18 '19 at 06:31
  • @Viky [You didn't try hard enough](https://coliru.stacked-crooked.com/a/a6926659c683b7ad). You should always look for cases that may overflow, and I guess you didn't consider these cases. Maybe you should be creating the base6 number as a string, not as an `int`. – PaulMcKenzie Jul 18 '19 at 06:32
  • First you should try to convert from decimal to binary. If you are able to do it then you must do it too. One tips for you is *think about boundary that is upper limit of ```int```* – Faruk Hossain Jul 18 '19 at 06:35
  • @Viky : you threw me for a loop with the unconventional approach you took. The code looks technically correct, but will only work for a limited range of values as others have pointed out. – Sander De Dycker Jul 18 '19 at 06:36
  • 4
    @Viky Build your base 6 number using strings / characters, not `int`. The basic loop works, but not the building of the number. – PaulMcKenzie Jul 18 '19 at 06:38
  • Wot Paul says. The int type is a simple binary and it makes no sense to try and load one with anything 'base 6', (mod the trivial 0-5 case). – Martin James Jul 18 '19 at 06:51
  • @Viky `res = (rem*i)+res;` -- That's your mistake. You need to make `res` some sort of a character array, and turn `rem` into a character digit (thus the `i` is no longer needed). Since the tags were changed from `C++` to `C`, that requires a little bit more work than simply using C++ `std::string` type. Probably use `strcat` or similar. – PaulMcKenzie Jul 18 '19 at 06:53
  • What happens with negative inputs? Also, remember that computers store numbers in binary, not decimal. Both decimal and 'heximal' (maybe a neologism for 'base 6'; 'hex' alone means 'hexadecimal' in computer circles) are non-native representations — things you represent with strings rather than simple numbers. – Jonathan Leffler Jul 18 '19 at 07:12

2 Answers2

4

Your solution will only work for a limited range of int.

Since base 6 will use more digits than a base 10 number, there will be a point where the base 10 number will generate a base 6 number that will not fit into an int, thus producing an overflow.

See this example.

One solution is to use strings to generate the base 6 number. The number is stored in a character array.

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

int main()
{
   const int maxdigits = 26;    /* max number of base 6 digits for a 64 bit int */
   int num=123456789, rem = 0;

   /* handle negative input */
   int tempnum = abs(num);

   int lastpos = maxdigits-1;

   /* initialize array, and initialize array to spaces */
   char res[maxdigits + 1];
   memset(res, ' ', maxdigits);

   /* null terminate */
   res[maxdigits] = 0;

   do 
   {
       rem = tempnum % 6;
       res[lastpos--] = rem + '0'; /* set this element to the character digit */
       tempnum /= 6;
   } while (tempnum > 0);
   printf("%s%s", (num < 0)?"-":"", res + lastpos + 1); /* print starting from the last digit added */
}

Output:

20130035113
PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
2

Converting a number to a given base should be done as a string.

Here is a simple and generic conversion function:

#include <stdio.h>

char *convert(char *dest, size_t size, int val, int base) {
    static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
    char buf[66];
    char *p = buf + sizeof(buf);
    unsigned int n = val;

    if (base < 2 || base > 36 || !dest || size == 0)
        return NULL;
    if (val < 0)
        val = -n;

    *--p = '\0';
    while (n >= base) {
        *--p = digits[n % base];
        n /= base;
    }
    *--p = digits[n];
    if (val < 0)
        *--p = '-';
    if (buf + sizeof(buf) - p > size) {
        buf[size - 1] = '\0';
        return memset(buf, size - 1, '*');
    } else {
        return memcpy(dest, p, buf + sizeof(buf) - p);
    }
}

int main() {
    char buf[32];
    int num;

    while (scanf("%d", &num)) {
        printf("%d -> %s\n", num, convert(buf, sizeof buf, num, 6);
    }
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189