Reputation: 2644
I tried the following code to convert a number from base-10 to another base. it works if there is no zero(0) in the destination base. check 79 and 3 and it properly prints 2221 which is correct. now try number 19 and 3, the result would be 21 instead of 201 which indicates something's wrong.
int x, y, a = 0, i, t, j;
cout << "enter two numbers" << endl;
cin >> x >> y; // x as the number in base-10 and x, as the destination base
a = x;
while (x >= y)
{
t = 1;
for (i = 0; x > y; i++)
{
x /= y;
}
cout << x;
for (j = 0; j < i; j++)
{
t *= y;
}
a = a - (t*x);
x = a;
}
cout << x<<endl;
Upvotes: 3
Views: 15310
Reputation: 206577
Using a recursive function is easier than using a while
loop for what you are trying to accomplish.
Here's working program.
#include <iostream>
void printInBase(int x, int y)
{
if ( x < y )
{
std::cout << x;
return;
}
int rem = x%y;
printInBase(x/y, y);
std::cout << rem;
}
int main()
{
int x, y;
std::cout << "enter two numbers" << std::endl;
std::cin >> x >> y; // x as the number in base-10 and x, as the destination base
printInBase(x, y);
std::cout << '\n';
}
Upvotes: 3
Reputation: 1
My answer.
Will also work on floating point numbers
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void radix(char *strNum, int base);
int main ()
{
radix("215.75", 8);
return 0;
}
void swap(char *a, char *b)
{
char temp = *a;
*a = *b;
*b = temp;
}
void radix(char *strNum, int base)
{
char res[100]={0}, tmp[100]={0}, floPoint[100]={0}, *p = 0, *q = 0;
int inum = 0, digitAfterDot = 3;
float fnum = 0.0;
if(strchr(strNum, '.'))
{
p = strNum + strcspn(strNum, ".");
fnum = atof(p);
}
inum = atoi(strNum);
for(p = res; inum; inum /= base, p++)
*p = (inum % base) + '0';
*p = 0;
if(fnum != 0.0)
{
p = floPoint;
*p++ = '.';
for(fnum *= base; digitAfterDot--; p++, fnum *= base)
{
sprintf(tmp, "%f", fnum);
inum = atoi(tmp);
fnum -= inum;
*p = inum + '0';
}
*p = 0;
}
for(p = res, q = res+strlen(res)-1; p < q; p++, q--)
swap(p, q);
strcat(res, floPoint);
puts(res);
}
Upvotes: 0
Reputation: 20730
Despite it could work, there is something conceptually wrong in this approach: you are essentially confusing numbers (the subject of arithmetic operations) with their textual representation (the sequence of digits used to represent them).
The type int
-by an external point of view- does not have a "base" (int will most likely have a base-2 internal representation, that's functional to the purpose to be manipulated by the arithmetic unit circuitry): it's just a thing to be added, subtracted multilyed, divided, and-ed, xor-ed etc.
When you do cout << a
what <<
do, is convert the a
number to a sequence of digit representing it into something readable. By default it happens to do it in base-10 digit represented as ASCII characters ('0'...'9').
What you are doing is convert a number into another number whose decimal representation resemble the base you are mapping. It can work in printing, but there is no arithmetic that can work with it. So int
is not a correct representation for them.
What you need is a different text-converter: something that takes an int
and another int specifying a base, and spits out the characters to represent your number.
Think to a class like
class based
{
int n, base;
public:
based(int num, int base) :n(num), base(base) {}
friend std::ostream& operator<<(std::ostream& out, const based& x);
};
to be used as
std::cout << bsed(79,3) << ' ' << based(19,3) << std::endl;
Now
std::ostream& operator<<(std::ostream& out, const based& x)
{
static const size_t N = 8*sizeof(int)+2; //base 2 is the widest, and is 32 or 64 + 2
char buff[N]; //keep space for sign + base2 + terminator
size_t X = N-1; //current writing character position
buff[X] = 0; //terminating char
--X; //prepare next left character
int n = x.n; //we will work on n
bool neg = (n<0); //keep negative sign
if(neg) n=-n; //and work always with posiotives
while(n) //we will reduce n down to 0
{
int digit = n%x.base; //mod is the last digit
n /= x.base; //next to the left
buff[X] = (digit<10)? char(digit+'0'): char(digit-10+'A');
--X; //next char
}
if(neg) buff[X] = '-';
else ++X; //no sign
out << buff+X << '(' << x.base << ')'; //the text from the point we reach towards left
return out;
}
This will output 2221(3) 201(3)
.
There is also a more portable way to do char(digit+'0')
etc. but considering normal digits, that's not more of what is needed.
Upvotes: 0
Reputation: 1169
int x, y, a = 0, i, t, j;
cout << "enter two numbers" << endl;
cin >> x >> y; // x as the number in base-10 and x, as the destination base
a = x;
t = 1;
while (x >= t*y)
{
t = t * y;
}
while (t)
{
cout << x/t << ' ';
x -= t*(x/t);
t /= y;
}
cout << '\n';
basically you weren't keeping track of what digit you were printing out, and your code can't tell when it would need leading zeroes. You could fix that by printing something like 2*(3^2) + 1*(3^0)
or by figuring out how many digits you need in advance as I did in the above code.
Upvotes: 1