Reputation: 21
I m trying to represent a positive integer in base(Each base is in the range 2 through 16) Its working but the output that I m getting is reverse of the required output for example the binary representation of '2' should be 10 but i m getting '01'. This is my code
#include<iostream.h>
#include<conio.h>
#include<math.h>
int main(void)
{
int b, number, i, result;
cout << "Enter the the number "<< endl;
cin >> number;
if (number < 0)
{
cout << "Number is not valid, as it must be greater than or equal to 0 \n";
system("PAUSE");
return 0;
}
cout<<"Enter the base value"<< endl;
cin >> b;
if(b < 2 || b > 16){
cout << "Base is not valid.\n";
system("PAUSE");
return 0;
}
cout << "The representation of the number with base " << b << " is" << endl;
while(number > 0) //number in base 10
{
result = number%b;
number = number/b;
i++;
if (result == 10)
{
cout << "A";
}
if (result == 11)
{
cout<<"B";
}
else if (result == 12)
{
cout<< 'C';
}
else if( result == 13)
{
cout<<"D";
}
else if (result == 14)
{
cout << "E";
}
else if(result == 15)
{
cout << "F";
}
else {
cout << result ;
}
}
getch();
}
I would appreciate some suggestions. Thanks
Upvotes: 0
Views: 1230
Reputation: 1407
It's a common issue when outputting numbers in a specific base. By taking the modulus of the division by the base you get the last (least significant) digit. You should maintain a buffer for the digits into which you can put each digit, then output the contents of the buffer in reverse order. Consider the following example:
vector<char> buffer;
while(number > 0) //number in base 10
{
result = number%b;
number = number/b;
i++;
if (result >= 10)
buffer.push_back((char)(result-10)+'A'); // alphabet is contiguous in ascii,
// so you don't need a huge if
else
buffer.push_back((char)result+'0');
}
for(i = buffer.size()-1; i >=0; --i)
cout << buffer[i];
for the conversion, it's even better to maintain a lookup table:
const char *hextable = "0123456789ABCDEF";
vector<char> buffer;
while(number > 0) //number in base 10
{
result = number%b;
number = number/b;
buffer.push_back(hextable[result]);
}
for(i = buffer.size()-1; i >=0; --i)
cout << buffer[i];
EDIT: If you would like to have the output in a string instead of the console, you can use a stringstream:
// ...
while(number > 0)
{
// ...
}
stringstream ss;
for(i = buffer.size()-1; i >=0; --i)
ss<< buffer[i];
string theString = ss.str();
note that you have to #include <sstream>
in order to have it defined.
Upvotes: 1
Reputation: 4409
result % base
will always grab the last character that needs to be printed. Therefore, we need to reverse the output somehow.
Recursive:
A recursive function that does the printing can reverse the output. As it is recursive, it uses the stack as a, well, stack. Thus we get a LIFO
ordering with our output.
Just replace your while
loop with a call to this:
rec_print(int number, int base)
{
rec_print(number/base, base);
int result = number / base;
if ( result <= 0) {return;}
result += result<10?'0':'A'-10;
cout << result;
return;
}
just be aware that stupidly high numbers in low base may cause a (ahem) stack overflow.
result += result<10?'0':'A'-10;
converts result
to ascii quite nicely as long as result >=0
and result < 16
Non Recursive:
How about this for a non-recursive version? Fills an 'array' (using vector
for runtime sizing) from the back and then prints it.
void print_number(int number, int base)
{
int result;
int number_of_digits = log(number)/log(base) +1; //+1 because '/' truncates and we want to always round up.
vector<char> output(number_of_digits+1); //vector<char> of the right size (+1 for null terminator)
output[number_of_digits+1] = 0; //null terminate.
while (number_of_digits--)
{
result = number % base;
result += result<10?'0':'A'-10;
output[number_of_digits] = result;
number /= base;
}
std::cout << &output[0]<<endl;
}
Works out how many digits are needed first, sets up a vector of the correct size to store it then writes each digit in from the end towards the front. It then grabs a pointer to the data in order to output it.
Upvotes: 1
Reputation:
To get the digits in the proper order, you can work "backward". First find the smallest power of the base that exceeds the number, extract the digit, and continue with lower powers.
// Find the smallest power
w= 1;
while (w * b <= n)
{
w*= b;
}
// Extract the digits
while (w > 0)
{
digit= n / w;
n-= digit * w;
w/= b;
}
This is not so efficient as it takes two divisions per digit.
Upvotes: 0
Reputation: 111339
You are printing the number in reverse: number%b
extracts the last base-b digit from the number, but it's the first digit that your print.
To print the digits in the right order you have to reverse the sequence somehow, so that the last digit is printed last. For example you could add the digits to a vector or write them in into a string, and the then reverse it.
Upvotes: 0