I am currently working on a basic program which converts a binary number to an octal. Its task is to print a table with all the numbers between 0-256, with their binary, octal and hexadecimal equivalent. The task requires me only to use my own code (i.e. using loops etc and not in-built functions). The code I have made (it is quite messy at the moment) is as following (this is only a snippit):
int counter = ceil(log10(fabs(binaryValue)+1));
int iter;
if (counter%3 == 0)
{
iter = counter/3;
}
else if (counter%3 != 0)
{
iter = ceil((counter/3));
}
c = binaryValue;
for (int h = 0; h < iter; h++)
{
tempOctal = c%1000;
c /= 1000;
int count = ceil(log10(fabs(tempOctal)+1));
for (int counter = 0; counter < count; counter++)
{
if (tempOctal%10 != 0)
{
e = pow(2.0, counter);
tempDecimal += e;
}
tempOctal /= 10;
}
octalValue += (tempDecimal * pow(10.0, h));
}
The output is completely wrong. When for example the binary code is 1111 (decimal value 15), it outputs 7. I can understand why this happens (the last three digits in the binary number, 111, is 7 in decimal format), but can’t be able to identify the problem in the code. Any ideas?
Edit: After some debugging and testing I figured the answer.
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
while (true)
{
int binaryValue, c, tempOctal, tempDecimal, octalValue = 0, e;
cout << "Enter a binary number to convert to octal: ";
cin >> binaryValue;
int counter = ceil(log10(binaryValue+1));
cout << "Counter " << counter << endl;
int iter;
if (counter%3 == 0)
{
iter = counter/3;
}
else if (counter%3 != 0)
{
iter = (counter/3)+1;
}
cout << "Iterations " << iter << endl;
c = binaryValue;
cout << "C " << c << endl;
for (int h = 0; h < iter; h++)
{
tempOctal = c%1000;
cout << "3 digit binary part " << tempOctal << endl;
int count = ceil(log10(tempOctal+1));
cout << "Digits " << count << endl;
tempDecimal = 0;
for (int counterr = 0; counterr < count; counterr++)
{
if (tempOctal%10 != 0)
{
e = pow(2.0, counterr);
tempDecimal += e;
cout << "Temp Decimal value 0-7 " << tempDecimal << endl;
}
tempOctal /= 10;
}
octalValue += (tempDecimal * pow(10.0, h));
cout << "Octal Value " << octalValue << endl;
c /= 1000;
}
cout << "Final Octal Value: " << octalValue << endl;
}
system("pause");
return 0;
}
It don’t understand your code; it seems far too complicated. But one
thing is sure, if you are converting an internal representation into
octal, you’re going to have to divide by 8 somewhere, and do a
% 8somewhere. And I don’t see them. On the other hand, I see a both
operations with both 10 and 1000, neither of which should be present.
For starters, you might want to write a simple function which converts
a value (preferably an
unsignedof some type—getunsignedright before worrying about the sign) to a string using any base, e.g.:
This shouldn’t take more than about 5 or 6 lines of code. But attention,
the normal algorithm generates the digits in reverse order: if you’re
using
std::string, the simplest solution is topush_backeach digit,then call
std::reverseat the end, before returning it. Otherwise: aC style
char[]works well, provided that you make it large enough.(
sizeof(unsigned) * CHAR_BITS + 2is more than enough, even forsigned, and even with a
'\0'at the end, which you won’t need if youreturn a string.) Just initialize the pointer to
buffer +, and pre-decrement each time you insert a digit. Tosizeof(buffer)
construct the string you return:
std::string( pointer, buffer + sizeof(buffer) )should do the trick.As for the loop, the end condition could simply be
value == 0.(You’ll be dividing
valuebybaseeach time through, so you’reguaranteed to reach this condition.) If you use a
do ... while,rather than just a
while, you’re also guaranteed at least one digit inthe output.
(It would have been a lot easier for me to just post the code, but since
this is obviously homework, I think it better to just give indications
concerning what needs to be done.)
Edit: I’ve added my implementation, and some comments on your new
code:
First for the comments: there’s a very misleading prompt: “Enter a
binary number” sounds like the user should enter binary; if you’re
reading into an
int, the value input should be decimal. And there arestill the
% 1000and/ 1000and% 10and/ 10that I don’tunderstand. Whatever you’re doing, it can’t be right if there’s no
%and8
/ 8. Try it: input"128", for example, and see what you get.If you’re trying to input binary, then you really have to input a
string, and parse it yourself.
My code for the conversion itself would be:
If you want to parse input (e.g. for binary), then something like the
following should do the trick:
It’s more complicated than
toStringbecause it has to handle all sortsof possible error conditions. It’s also still probably simpler than you
need; you probably want to trim blanks, etc., as well (or even ignore
them: entering
01000000is more error prone than0100 0000).(Also, the end iterator for
findhas a- 1because of the trailing'\0'the compiler inserts intodigits.)