This course will introduce you to C++ 11 and teach you about syntax fundamentals.

Im trying to write code that will take a decimal and convert it to it's 2's complement. Ive been trying to figure it out but i can only get it to working using the functions as void, not string as the requirements have been specified. The only way that has worked so far is through iteration and that is not allowed.

The functions rquired are basically what is being the part that wont allow me to continue.

Function main() calls function string convert(int decimal, int n) that receives the number and returns a string that represents the corresponding binary number in n bits format, where n is the minimum number of bits used to display the binary number.

Function convert() will have to call the *recursive* function string dectobin(int decimal) that receives the decimal number and returns a string that represents the corresponding binary number in free format (that is, with just as many bits as needed to represent the value). Thus, it is the task of convert() to add the (0's and 1's) to the string returned by dectobin() so that the binary number is in n bits format.

The first int in the txt file will be taken in through string convert() as the number of bits, then using that to set the displayed number of bits from the 2's complement representation from function string dectobin().

Example of input:

8

123

-45

72

0

-1534

2341

-8

Example of output:

Decimal:2's complement (8 bits minimum)

---------------------------------------

123 : 01111011

-45 : 11010011

72 : 01001000

0 : 00000000

-1534 : 101000000010

2341 : 100100100101

-8 : 11111000

(i had a previous post about a different part of this that i was working on until i found out it wasnt recursive at all and that i basically had to start from sqaure 1.)

The functions rquired are basically what is being the part that wont allow me to continue.

Function main() calls function string convert(int decimal, int n) that receives the number and returns a string that represents the corresponding binary number in n bits format, where n is the minimum number of bits used to display the binary number.

Function convert() will have to call the *recursive* function string dectobin(int decimal) that receives the decimal number and returns a string that represents the corresponding binary number in free format (that is, with just as many bits as needed to represent the value). Thus, it is the task of convert() to add the (0's and 1's) to the string returned by dectobin() so that the binary number is in n bits format.

The first int in the txt file will be taken in through string convert() as the number of bits, then using that to set the displayed number of bits from the 2's complement representation from function string dectobin().

Example of input:

8

123

-45

72

0

-1534

2341

-8

Example of output:

Decimal:2's complement (8 bits minimum)

--------------------------

123 : 01111011

-45 : 11010011

72 : 01001000

0 : 00000000

-1534 : 101000000010

2341 : 100100100101

-8 : 11111000

(i had a previous post about a different part of this that i was working on until i found out it wasnt recursive at all and that i basically had to start from sqaure 1.)

Then, make a main function which provides the input arguments (make comments about their meaning) and calls the function(s). Then, make the necessary printouts. With that, you may ask specific questions how to implement the recursive function.

Regards, Alex

P.S. Can you explain the purpose of the second argument of convert function. I didn't get it.

>> -1534 : 101000000010

>> -8 : 11111000

when you implement with proper method, you wont get the values like above. becase the number of bits should be constent (may be 8 multiplies..)

fine,

refer the implementation of itoa function with radix 2. this will definetely help you if you know how to implement recursive function. in this function they may use % operator. since you want to conevert only to binary, you can use shift operators. and before iterating you can find the number of bits for positive numbers, so that you can increase bit performance.

Admin:

I hope i am not voilating EE rules as i have given just some tips. If i am , please let me know.

The minimum number of bits that the result must contain (for 0-padding at the beginning if needed).

>> when you implement with proper method, you wont get the values like above.

Sure you can ... the recursive function can stop at any time, thus returning a string of any length.

@ststoleson : I would suggest to start with the dectobin recursive function. It's not hard ... just let it treat one bit (the % and / operators can help you there), and then call the function recursively ...

Once you have the dectobin recursive function, you can create the convert function, that will call the dectobin function, and pad the result with 0's if needed.

That's it. Give it a try, and post your code here, so we can have a look at it ... and help you where needed.

Maybe the >> operator and the & operator is the better choice.

The >> operator shifts bits of an integer to the right (padding with zero bits at the left), e. g.

unsigned int ui = 123; // 00000000000000000000000001

ui = ui>>1; // 00000000000000000000000000

ui = ui>>4; // 00000000000000000000000000

The assign statements can be shortened by using th eoperator >>=

ui >>= 1;

The & operator compares bits of two integers and the result will have a 1 bit only where both operands have a 1 bit (always right-justified).

ui1 = 9; // 1001

ui2 = 21; // 10101

ui3 = ui1 & ui2; // 00001

So, you can test whether a bit at position x was set by

if ((ui & (1<<x)) != 0)

cause

1<<x

moves the 1 bit at position 0, to position x (e. g. 1<<3 == 2^3 == 8 == "1000" )

so, the (ui & (1<<x)) must have all bits zero beside of the bit at position x which is 1 when ui has a 1 bit at position x.

So you can test in your recursive function whether the bit at pos 0 was 1 by

if (dec & 1)

and the next number for recursion is

dec >> 1

Regards, Alex

I didn't want to confuse him since this is probably one of the first programs he does with C++

btw, the generated code (by the compiler) should be pretty much the same.

Yes, but the bit operators are more appropriate for a task regarding bits than modulo 2 and division by 2. Though the latter may be simpler for a newbee in general, it requires a further abstraction to deduce from that to the bits.

Let's wait for feedback to decide what is the better approach.

Hmmm. Do you remember the thread where I assumed that a modulo 11 applied to smaller numbers was faster than applied to bigger numbers? Modulo means division and to turn a division to a bitshift operation means that the compiler actually checks for operand == 2 and make the optimization then. Possible, but I wouldn't bet for it.

We're talking about modulo 2 here ... Any self-respecting modern compiler will realize that it's better to do an & (and in case of division by 2, will realize that a right shift is better), and will generate the exact same instructions in both situations.

division by 11 is slightly more complicated, as there's no way of doing it with one shift. It needs a few instructions, and these might or might not be faster than a single division instruction.

However, you can be pretty sure that a single shift instruction will be faster than a single division instruction, and the compiler knows that, and will thus properly optimize a division by 2 to a right shift.

Personally, I'd use & and >> too, but it depends on the level of experience of ststoleson ...

>> -1534 : 101000000010

>> -8 : 11111000

>> Sure you can ... the recursive function can stop at any time, thus returning a string of any length.

i didnt understand, can you tell me how to define differnt number of bits for -ve values.

Actually you convinced me to try it with modulo and division. If the recursive function accepts any arbitrary base (2 ... 16), the first three statements of the function are like

static string digits = "0123456789abcdef";

if (number == 0) return str;

int idxdigit = number%base;

The last statement would be the recursive call in a return statement. That's all (beside of padding up with zeros) in the calling function.

Bit shifts maybe more efficient for bases that are a power of 2. But with the above I can make conversions to decimal string or 'dozen' base as well.

number: 12345

base: 2

12345 ---> 11000000111001

number: 12345

base: 16

12345 ---> 3039

number: 12345

base: 10

12345 ---> 12345

number: 12345

base: 12

12345 ---> 7189

Yes, but then you lose the advantage of the compiler being able to optimize for division by a power of 2.

So, you sacrifice (a bit of) speed for genericity.

Using a templated function would be better if your aim is genericity

@ststoleson : ignore what I just said - it's a discussion between experts, and not relevant for what you have to do ;)

>> i didnt understand, can you tell me how to define differnt number of bits for -ve values.

I don't know what you mean by -ve values, but when you write a recursive function, you can make it stop whenever you want ... In this case, that would be the moment the value becomes 0. That way you only process the number of bits that need to be processed.

but for negative values MSB will always be 1. so the number of bits for negative values will always be same.

IMO, negative numbers should be handled by the 'convert' function - same as the padding - and not by the recursive function.

The recursive function should handle natural numbers (>= 0) only. I used a unsigned int as input type because of that, but you could call the recursive func like

s = intToStr(-12345, 2, s);

without problems.

Note, the modulo operator % is not (well) defined for negative operands though compilers won't have problems with it normally.

>> IMO, negative numbers should be handled by the 'convert' function - same as the padding - and not by the recursive function.

Exactly. The recursive function should only have to deal with positive numbers.

No we can make it to handle both numbers. But the number of bits will be constant(8bits, 16bits...)

That's not what was required by the exercise (see the example output), nor does it make sense, because for large negative values, the recursive function would waste most of its recursive calls for processing the 0's between the sign bit and the value.

If you're still not convinced, then read this part of the assignment again :

the *recursive* function string dectobin(int decimal) that receives the decimal number and returns a

string that represents the corresponding binary number in free format (that is, with just as many bits

as needed to represent the value). Thus, it is the task of convert() to add the (0's and 1's) to the

string returned by dectobin() so that the binary number is in n bits format.

the above statment can be applicaple only for +ve numbers.

lets take two set of size (8bit, 16bit)

for 8 bit:

the value of 7 will be 111

-7 1111 1001

for 16 bit:

the value of 7 will be 111 (same as 8 bit)

-7 1111 1111 1111 1001

so we should decide how many bits output is required for negative values before converting.

Exactly ;) That was my point ...

>> so we should decide how many bits output is required for negative values before converting.

Just read the requirements :

Thus, it is the task of convert() to add the (0's and 1's) to the

string returned by dectobin() so that the binary number is in n bits format.

In other words : convert has one parameter that gives the minimum number of bits. So, bits are prepended if the number of bits returned by dectobin is smaller than this minimum.

Note that the assignment explicitly states that 0's and 1's can be prepended ... Why do you think it mentions 1's ?

i dont think the statment says to ommit (leading) 1's. even if says, thats not the correct way to convert.

and can you tell me how do you find how many bits are required for a given -ve number to create a char* memory?

- it may be passed positive or negative numbers as 'int' is a signed int.

- the number of bits of a 'int', e. g. 32, is one of the parameters we have to consider when dealing with negative numbers.

There is not a single hint in the requirements that 8bit or 16bit boundaries should be used to pad ones to the output string. We don't even have a hint that negative numbers should be printed with their complementary unsigned representation. Though it may be unusual for binary string representation to add a '-' sign at the beginning (e. g. -10011 for decimal -19) I can't see a reason why it is not allowed. If we would do so for any base from 2 ... max bits of int, we are along with the specs and would not mixup with the quite different question how negative numbers were represented in nowadays computer architecture.

You don't need to - this is C++, and you can use std::string. If you need to allocate memory for the string, then take the maximum amount of bits in an int (usually 32).

>> There is not a single hint in the requirements that 8bit or 16bit boundaries should be used to pad ones to the output string. We don't even have a hint that negative numbers should be printed with their complementary unsigned representation.

Take a look at the examples :

123 : 01111011

-45 : 11010011

72 : 01001000

0 : 00000000

-1534 : 101000000010 // <--- negative value with 12bit output (the first 1 is the sign bit)

2341 : 100100100101

-8 : 11111000 // <--- negative value with 8bit output (the 5 first bits are "sign bits")

So, all output binary values have to be at least 8 bits wide, and if more, then only 1 sign bit is needed !!

NO. only fist bit is sign bit, all others are data.

Notice the ""'s around "sign bits" - it means that you shouldn't take it literally ... In other words, the base negative value is 1000, and that is extended to 11111000 because the minimum size is 8 bits. In other words, the sign bit is extended.

That's the entire reason for having 2's complement notation : because you can easily extend it, easily add it, etc.

Towards Infinity08.. To answer your question about the experience level i have, id say mabye about 2 semesters, im comfortable with basic functionality and such but advanced concepts is what im having a tough time working out now :-\ , I noticed your very early post and ill start with that approach with starting with the recursive function first and working my way from there..

Towards itsmeandnobodyelse.. thanks for your advice too, ill check into what you have said and try to use that as some help towards my issue.

I guess from now on ill just post code snippets from what i have, and try to see what i can do from there, just feel overwhelmed with the part about keeping it as a string, instead of a void function (dectobin and convert)

Cheers everyone

what im trying to do is since i have dectobin converting the int decimal to string binary... i have the function convert calling to it to do so, inside the convert function i have it choose if the number is pos, neg, or 0.

if the 0 then returns 0 to save time, if its negative i have it multiply the decimal by -1 to get a positive number for teh dectobin function to use.

I guess my specific question is now that i have the binary string.. how do i get each specific bit and check if its a 1 or 0 such as for the 2's complement

example if its -6 as the decimal, i have the convert function turn it into +6 then convert it, now what i want to do is use a stack or something of the sort to change to 2's complement so that it still will output as a -6 binary set.

any ideas?

heres my code ive written so far....

(the commented out section of if statements in the dectobin is just a different method of recursion i was trying)

```
#include <iostream>
#include <sstream>
using namespace std;
void dectobin(int num, int base);
void convert(int n, int decimalnum, int base);
int StringLength(char inputString[])
{
int length = 0;
for (int i = 0; inputString[i]!= '\0'; i++)
length++;
return length;
}
int main()
{ char choice;
int decimal;
int base;
int bits;
base = 2;
cout << "enter decimal: ";
cin >> decimal;
cout << endl;
cout<< "Decimal " << decimal << " = ";
convert(bits, decimal, base);
cout << " binary" <<endl;
cout << "do it again? enter y or n: ";
cin >> choice;
switch (choice)
{
case 'y':
return main();
break;
case 'n':
return 0;
break;
}
}
void convert(int n, int decimalnum, int base)
{
int code= 0;
if (decimalnum > 0)
{
dectobin(decimalnum, base);
}else
if (decimalnum <0)
{
decimalnum = decimalnum * -1;
dectobin(decimalnum, base);
}
if (decimalnum==0)
{
cout << code;
}
}
void dectobin(int num, int base)
{
string str;
stringstream out;
int i;
/*
i = num % base;
if( num/base > 0)
{
string test;
string str;
stringstream out;
out << i;
str = out.str();
test = dectobin ( num/base, base );
cout << "here is hello from " << num << " and my result is: >" << test << "< !" << endl;
return test;
}
if ( num/base == 0)
{
i = num % base;
string str;
stringstream out;
out << i;
str = out.str();
return str;
}
*/
if( num > 0)
{
dectobin (num/base, base);
i = num % base;
out << i;
str = out.str();
cout << str;
}
```

The dectobin must return the final string. You also must pass the string so far so that the next recursive call can 'append' a new character.

string dectobin(int num, int base, const string& strnum);

>>>> if( num/base > 0)

Better: simply return the given argument string when num == 0. If you don't use a 'int num' but a 'unsigned int num', the dectobin has not to care for negative integers. That is the task of the 'convert' function (see discussion above).

>>>> string test;

>>>> string str;

>>>> stringstream out;

You neither need local strings nor stringstream. Note if you have

int digit = num%base;

and assumed that base is between 2 ... 16, then digit is a number in the range of 0 to 15 (16 digits). If you would make a static string constant

static const string all_possible_digits= "0123456789ABCDEF";

you can use the result of the modulo to get the corresponding digit character. No conversion, no temporary strings.

Regards, Alex

I'll only comment on your dectobin function, because that's the first thing you should get working.

>> i have the functions as bins cause i was having so much problems using the functions as strings :-\ ....

The function has to return a string, because you need to somehow get the result from the function. Returning something from a function happens like this :

int getValue() {

return 5;

}

This function returns an int, and more specifically, the int 5. When you call it like this :

int value = getValue();

then value will be set to 5, because that's what the function returned.

The same is true for strings :

std::string getStr() {

std::string str = "hello";

return str;

}

and called like this :

std::string str = getStr();

will set str to the string "hello", because that was what the function returned.

So, the signature of the dectobin function should not be :

void dectobin(int num, int base);

but :

std::string dectobin(int num);

as in the assignment.

Further, as Alex said : you don't need stringstreams. You can add a character to a string by doing :

str += "a";

(this will add the character 'a' at the end of the string).

This part of your code looks very good :

if( num > 0)

{

dectobin (num/base, base);

i = num % base;

Now you just have to add the correct character to the string.

Towards itsmeandnobodyelse: I tried looking into

- static const string all_possible_digits= "0123456789ABCDEF";

but i have no idea how this works, nor could i figured it out, is it static casting? sorry for being a dumb@$$...

what i did find however is a function that will convert it for me, and it works good from what i can see as i tested it by couting during each conversion in the function itself, for when i cout it is in the right order, and it passes the bit each time through the "stringify" function.

So now i have something geared more toward what is being asked of but now im stuck on getting to return the whole string of values instead of just the LSB as it seems its doing now

Towards Infinity08:

I see what you mean about how to add a character to a string, though it adds it on the end so i dont know how you would add it to the front of the string. Like i said earlier, i fixed it so that its simpler and handles only base 2. I know you said to go to what alex said about the static const string but like i said to him, i used that function string stringify().. am i just making this harder on myself or is static string easy to use and im just a dummy?

I was thinking now that i have to convert to string, is there a way i can store y each time its passed through so that itll return the whole enchilada?

i've attached the updated code

btw i appreciate y'all providing me your insight/ideas

```
** Is my dectobin function now w/ fixed base and implementation of the int to string converting function. **
string dectobin(unsigned int num)
{
string b;
int i;
string y;
string array[9];
if( num > 0)
{
b = dectobin(num/2);
i = num % 2;
y = stringify(i);
}
cout << y; // will cout the right binary string
return y;
}
** here is the whole code as it stands now with the inclusion of the stringify function **
#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>
using namespace std;
string dectobin(unsigned int num);
class BadConversion : public runtime_error
{
public:
BadConversion(const string& s) : runtime_error(s)
{ }
};
string stringify(int x);
int main()
{
string x;
int decimalnum;
cout << "enter decimal: ";
cin >> decimalnum;
cout << endl;
cout<< "Decimal " << decimalnum << " = ";
//x = sets dectobin as a string variable just for now
dectobin(decimalnum);
//cout << x; outputs the value of dectobin
cout << " binary" <<endl;
system("PAUSE");
return 0;
}
string dectobin(unsigned int num)
{
string b;
int i;
string y;
string array[9];
if( num > 0)
{
b = dectobin(num/2);
i = num % 2;
y = stringify(i);
}
cout << y; // will cout the right binary string
return y;
}
string stringify(int x)
{
ostringstream o;
if (!(o << x))
throw BadConversion("stringify(int)");
//cout << "THIS IS STRING: ";
return o.str(); // converts int to string
}
```

Again: you have to pass the string so far

string dectobin(unsigned int num, const string& s);

>>>> string array[9];

You don't need that

>>>> if( num > 0)

Better handle case num == 0 first.

if (num == 0)

return s; // return the string you got passed

>>>> b = dectobin(num/2);

That is too early. You first need to append the current digit to the string.

i = num % 2;

y = stringify(i);

b = dectobin(num/2, s + y); // here you append the '0' or '1'

>>>> return y;

You have to return b.

return b;

>>>> but i have no idea how this works, nor could i figured it out,

>>>> is it static casting?

No, a statically defined variable in a function simply was created once and not with each call as it was with non-static variables. The 'all_possible_digits' is just a constant literal (and it doesn't matter whether you make it static or not). You could use it directly in dectobin after you calulated the last digit with modulo:

string dectobin(unsigned int num, int base, const string& s)

{

// define a literal for all possible digits

const string all_possible_digits= "0123456789ABCDEF";

...

int i = num % base; // here you got the digit as a number from

// 0 to base-1

char c = all_possible_digits[i]; // that way you got the character

Note, in case of base == 2, the value of i is either 0 or 1. So, the digit character is '0' or '1' which is all_possible_digits[0] or all_possible_digits[1].

You also could use it in your function 'stringify':

char stringify(int x)

{

// define a literal for all possible digits

const string all_possible_digits= "0123456789ABCDEF";

if (x < 0 || x >= all_possible_digits.length

throw BadConversion("stringify(i

//cout << "THIS IS STRING: ";

return all_possible_digits[x]; // converts int to char

}

Note, I changed the return type from string to char cause you always were retrieving one single char only.

```
string dectobin(unsigned int num)
{
string b;
int i;
if( num > 0)
{
b = dectobin(num/2) +
static_cast<char>(i = num % 2 + 48);
return b; // <--- return the concatenation (b + y)
}
return ""; // <--- return the empty string (in case num == 0)
}
```

y has been replaced with static_cast<char>(i = num % 2 + 48)

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.

That's easy, just invert it :)

str = "a" + str;

>> am i just making this harder on myself or is static string easy to use and im just a dummy?

I don't think I suggested to use a static string ... it wouldn't be a very good design imo.

>> Again: you have to pass the string so far

You don't have to, since the string so far is RETURNED by the function.

>> is there a way i can store y each time its passed through so that itll return the whole enchilada?

You're so close, that I'll just make a few modifications and comment them :

Open in new window