URGENT!!! Write a program that produces the binary equivalent of a non-negative integer input by the user.

Pages: 123
Sigh. I guess I am old and cranky, but not yet retired. Not a prof or anything. Ironically for a programmer I can't type well.

Lets take a few of these..

what is Boolean?
Good, you looked it up. Yes, its a true/false. Every condition you type is a Boolean, eg if(x < 3) is evaluated down to a true/false (which is 1 and 0 as integers in c++). Its a type in c++, so like int, you can make a Boolean variable.

so something like this: (I will redo my code with comments and adding these ideas into it later).
bool foundaone = false;
…. in my from the left approach, to ignoring leading zeros then...
the first time you find a '1' you set this to true:
foundaone = true;
and you check it
if(foundaone) //adds the '1' or '0' to your growing output string.
but if you didn't yet find a one, you are finding leading zeros, so you do nothing.


> log base gives you how many digits it has in that base, with a roundoff.
lg(22) is 4.5 as you said. 22 in binary has 5 digits. Adding 1, you get what you needed (int)(5.5) is 5, or you can set pow(2,63) to pow(2,5) and this will also skip leading zeros. Lets do it by hand.
1 2 4 8 16 32 (2 to the 0,1,2,3,4,5).
the biggest a 4 digit binary number can be is 15 (1111) 8+4+2+1
so 4 digits are not enough. adding 16, we get 31, which is big enough to hold 22, so 5 digits is the right amount in binary for 22. The log function is doing all that logic we did by hand there for you: it answers the math question "two to what power is 22". the powers of two and its base are all tied together, though, as you can see in the by-hand breakdown. It works for base 10 as well. how many base 10 digits do you need for 12345? (well, clearly, you need 5, you can just see this since we wrote it in base 10). But the log 10 of 12345 is 4.09. Here again adding 1 (5.09) and taking (int) of it gets you the answer.

all that to say pow(2, (int)(log2(value)+1)) would drop the leading zeros and give you the binary form of 22 using my original code.


You have lost me again in your explanation. Add what letter integer to s and why?

Your end goal is a string of characters, each of which is either '1' or '0' (these are letters, with the single quotes). For each digit, you are figuring out which one it is and appending that into the final answer.

doing it the professor's way (he says as much) generates the binary in reverse.
one way to avoid this is to make a temporary variable that contains the new digit concatenated with what you already found.
so using his method, for 22, to get 10110, you divide by 2 etc,
you find 0.
then you find 1
then 1
then 0
then 1... see how its backwards?
but adding it to a string like this, in the same order:
tmp = '0' + s; (s is empty). tmp is now "0";
s = tmp; //put tmp back over s, s is now "0".
tmp = '1' + s; // the next one you found above, tmp is now "10"
s = tmp; //s is now "10";
tmp = '1' + s … // tmp = "110"
s = tmp; // repeating this, as its in the loop with the digit extraction...
tmp = '0' + s; //tmp is "0110"
… etc tmp = '1'+s; // "10110" //hey, its our friend 22

you are not dumb at all. now you are actually doing what I was trying to get you to do, which was to think and ask good questions. You looked up bool, you attempted the log 22 to understand. I was intentionally being a little frustrating to get you to stop copying and pasting code snips together. The hardest thing to learn as a new coder is to stop coding and think it through first.

Speaking of bools, if you had not yet seen them, this would be nonsense to you.
s+= bl[ (val&p)!=0];
bl is an array with two letters. the 0th position in the array (bl[0] is the letter '0'). It is the 2 digits in binary, as characters.
but, as I noted above, Booleans are true/false which is also 1/0 in integer values. And as I said, conditions evaluate to Booleans.
so that cryptic line says 'is value bit-wise and with p not equal to zero'. if that is true (1) you get the letter '1' as it is going to bl[1]. if it is false, you get bl[0] which is the letter '0'. so, its the same as saying
if(the bit represented by p, which is 2 to some power each loop iteration, is a 1 in val) then append '1' to the string. Else append '0' to the string.

So what my original code does is this:
22, 10110 is 16+4+2 (powers of 2, what each binary digit MEANS).
I come along with p, which is a power of 2, lets say 16. that is 10000 binary.
10000 //p
10110 //22
it looks at the first bit of both of those, which effectively checks whether that bit in 22 is a 1. If it is, we get '1' (and it matches so we do get the '1' here. )
after that it tries the next power of 2: 8, which is 1000 in binary
01000 //8
10110 //22 this time they do not match, and its a zero.


Its late, but hopefully some of this is helpful. If you can see how what I did is coming across the number from the most significant bit down, instead of least significant bit up, and how it builds the string left to right, which is more natural than right to left for writing numbers (think about how you write 1234 on paper, you write the 1 first!) … if you see how it works, you will be way ahead of your peers.

if you also understand how lastchance's recursive approach reverses the string using the recursion call stack, you will far enough ahead that you won't need this class :P. That one may be best left for later, but if you do want to dig into it...
Last edited on
dumdumFlame wrote:
And since num changes throughout the program it doesn't have anything to show at the end.

So, keep a copy: one that you aren't going to change. You can write that copy out at the end.



dumdumFlame wrote:
And how can we get it to show the binomial code like it used to?

You have to create a string with the binary representation in as you go along. In @dhayden's cleaned-up version of your code he has given clear hints of where to do this. Look at his instructions:
dhayden wrote:
Let's look at line 13. num % 2 computes the remainder of num/2. So if this statement is true then you need to add code to add "0" to the string s. If the statement is false, then you need to add code (at line 16) to add "1" to s. See if you can write that code.

He couldn't be more explicit.



jonnin wrote:
if you also understand how lastchance's recursive approach reverses the string using the recursion call stack

There is NO NEED FOR REVERSAL ANYWHERE. Even in a loop you simply get the successively-higher-value binary digits by prepending to a string, not appending.

Thus, for example, 22 decimal = 10110 binary
Start with a string, result="" (i.e., empty string). Then pre-pending the successive digits from the right:
result becomes '0'+ result
result becomes '1'+ result
result becomes '1'+ result
result becomes '0'+ result
result becomes '1'+ result

At the end, result is 10110

Your teacher did NOT say to reverse anything; he/she just pointed out that you would be acquiring the digits (making use of the modulus, or remainder, operator %) from the right.


Finally, @dumdumFlame, please make use of the format menu. In particular, make sure that you put code tags (the first item in the format menu) around code samples. Otherwise your code will lose all formatting when posting and will be incredibly difficult to read.
Last edited on
... prepending to the string is reversing it (the string is the reverse of what you obtained). I think that is just semantics. We did the same thing, except I used 2 variables (without any good reason, really, I was focused on the integer stuff and got sloppy on the string).
Last edited on
commented +showing the log & the conditional leading zero ideas. Minor changes to fit that in.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <string>
#include<cmath>
#include <iostream>
using namespace std;

int main(int argc,char **argv)
{	
char bl[] = {'0','1'}; //the letters used in s, the output string. 
string s; 
uint64_t value = 0;

cout << "enter value> ";//added, get a value from user to test
cin >> value;
uint64_t p = pow(2,(int)log2(value)); //find how many digits it will have in binary, skips leading zeros this way. 
do
  {
	s+= bl[ (value&p)!=0];  //p represents 1 bit in binary, a power of 2 is 1 bit, eg 16 is 10000 
  //so this says if the bit represented by p is 1 in value, add '1' to the string, else add '0' to the string. 
  //it does this by converting the question is value BITWISE ANDED with p equal to zero?  Into a boolean (1 or 0)
  //result.  The 1 or 0 result are used to get the first ([0]) or second ([1]) location from bl, which is the desired
  //character.   Concatenate the desired character onto the string.  
	p = p>>1; //this divides p by 2.  This is a bit-shift to the right, so 1000 becomes 100 in binary, which is the 
	//same as divide by 2. 
  }while(p); //it will stop when p==0 which happens when integer division of 1/2 is zero, 
  //which is the last bit (the 1's position)

cout << s << endl;

return 0;	
}

/*
//alternate version skips leading zeros with a condition example.  
int main(int argc,char **argv)
{	
char bl[] = {'0','1'}; //the letters used in s, the output string. 
string s; 
uint64_t value = 0;
bool skip = false;

cout << "enter value> ";//added, get a value from user to test
cin >> value;
uint64_t p = pow(2,63); //find how many digits it will have in binary, skips leading zeros this way. 
do
  {
	skip |= (value&p)!=0; //when we found the first 1, this is true forever after. 
    if(skip) //stop skipping leading zeros, we are done with that. 	
	s+= bl[ (value&p)!=0];  //p represents 1 bit in binary, a power of 2 is 1 bit, eg 16 is 10000 
  //so this says if the bit represented by p is 1 in value, add '1' to the string, else add '0' to the string. 
  //it does this by converting the question is value BITWISE ANDED with p equal to zero?  Into a boolean (1 or 0)
  //result.  The 1 or 0 result are used to get the first ([0]) or second ([1]) location from bl, which is the desired
  //character.   Concatenate the desired character onto the string.  
	p = p>>1; //this divides p by 2.  This is a bit-shift to the right, so 1000 becomes 100 in binary, which is the 
	//same as divide by 2. 
  }while(p); //it will stop when p==0 which happens when integer division of 1/2 is zero, 
  //which is the last bit (the 1's position)

cout << s << endl;

return 0;	
}
*/


Ok thanks guys I see how this reverses from what we had in the end but now we are back to where it doesn't show the equations it used to. Do we put that in at line 26? Is there any way we can combine what we had and what you just made without them interfering and then it outputs both the answer and the work? I tried doing it myself but something about having a do while and an if else or something wasn't working.
Last edited on
SHIT NVNM I THINK I DID IT
lol jk u guys did it I put two things together and it worked. I added another do while with the if else inside and changed num to value. Then it worked.
Actually when I put the thing in my Dev-C++ 5.11 it didn't work it said: 'uint64_t' was not declared in this scope, value was not declared in this scope, expected ';' before 'p', and that 'p' was not declared in this scope twice.
Anyone know why it doesn't work. Because that's how I turn things in and share them.

I think it's because Dev-C++ is in C++98 not 11 or 14.
Is there a way we can make it work for both?
Last edited on
Dev C++ 5.11 should be set to default to C++11 as the language standard. For the fixed width integer types like uint64_t you may need to #include <cstdint> also.

C++11 is the newest language standard Dev-C++ can be set to. That is seriously limiting. If you can upgrade to a newer compiler/IDE. Visual Studio 2019 for Windows, Code::Blocks 17.12 for other operating systems (including Windows).

I tried jonnin's code with my Dev-C++ and had no problems with it.
It is set to C++98 forsome reason because when I do it I get certain errors that only happen when I Cpp.sh in C++98. I put in the <cstdint> but I got this:

// Copyright (C) 2007-2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

/ You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.

/** @file bits/c++0x_warning.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/

#ifndef _CXX0X_WARNING_H
#define _CXX0X_WARNING_H 1

#if __cplusplus < 201103L
#error This file requires compiler and library support for the \
ISO C++ 2011 standard. This support is currently experimental, and must be \
enabled with the -std=c++11 or -std=gnu++11 compiler options.
#endif

#endif

I think this thing is saying it currently isn't updated to 2011?

Jonnins code isn't the code I'm using I'm using:
http://cpp.sh/44sz5

wait I just realised a couple errors still in it.
Enter a positive integer: 22
22/2 = 11 remainder = 0
11/2 = 5 remainder = 1
5/2 = 2 remainder = 1
2/2 = 1 remainder = 0
1/2 = 0 remainder = 1
Done, since the quotient = 0.
so, 0 decimal = 10110
this is the output if I put in 22
and it should say:
so, 22 decimal = 10110
So the question is how do I put the inputted number at the start at the end too?
Other than that it's one hundo percent what I need
Last edited on
Anyway my prof will not accept this because of the thing it uses we haven't covered in class.
We have never discusses the include file cstdint
We have never had a main header we anything between the parentheses.
We have not covered arrays yet.
We have never used the type unint64_t
We have never used the & operator
We have only used the >> operator for I/O

The idea is to use a loop to repeatedly divide the number entered by the user by 2 to obtain the remainder (which would be 0 or 1). Then, starting with a blank string variable concatenate a '0' or '1' character to the string to create the binary representation of the number as a string when the loop is done. Just be careful to concatenate those character is the correct way. See in the example that I gave in the assignment of converting 22 into binary. When you start dividing 22 by 2 to get remainders, those are the binary digits of 22 backwards.

Repeating my big hint from a few days ago:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <string>
#include<cmath>
#include <iostream>
using namespace std;
int
main(int argc, char **argv)
{
    int num;
    string s;
    cout << "enter a positive integer: ";
    cin >> num;
    while (num) {
	if (num % 2 == 0) {
	    // num/2 has remainder 0
	} else {
	    // num/2 has remainder 1
	}
	cout << num << "/2 = " << num / 2 << " remainder = " << num % 2 << endl;
	num = num / 2;
	cout << num << endl;			 //I think I can get rid of this right?
    }
    cout << "Done, since the quotient = 0." << endl;
    cout << "so, " << num << " decimal = " << s << endl;
    return 0;
}

If you remove the debug statements, this program is three statements away from the answer, without any of the stuff you haven't covered.
Thx for trying to help this is due tomorrow I give up.
Last edited on
Why don't you just read @dhayden's post above? He has told you (almost) everything to do.
Ok what is the debug statements???
Ok what is the debug statements???

The three items with comment statements. He expanded on it in more detail here:
http://www.cplusplus.com/forum/beginner/268962/#msg1157736


The only other thing I would add is to store a copy of num so that you could write it out as the original decimal number at the end - but that's a trivial matter.
I'm hoping I can be of some help to the OP in understanding what the algorithm is doing. Maybe spelling things out more clearly can help them understand why and how to use a loop to do the task.

I left comments in the loop body to explain what statements need to be written within.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    /*
        For the example input of 22:
        dividend starts at 22.
        divisor is always 2 because that's the numeric base we're converting to (binary)

        Iterations:
                                                  The binary string is built out of the
           dividend ----.   .---- divisor         remainders from each step. --.
                        |   |                             .--------------------'                  
                        v   v                             v
        1.  quotient:  22 / 2 = 11, remainder:  22 % 2 =  0     }
                        .-------/                               |
                        |    (quotient here becomes             |
                        |     dividend for next iteration)      |
                        v                                       |
        2.  quotient:  11 / 2 =  5, remainder:  11 % 2 =  1     |
                        .-------/                               |
                        |    (and so on...)                     |
                        v                                       |
        3.  quotient:   5 / 2 =  2, remainder:   5 % 2 =  1     |____Final string reads
                        .-------/                               |    bottom to top
                        |                                       |
                        v                                       |
        4.  quotient:   2 / 2 =  1, remainder:   2 % 2 =  0     |
                        .-------/                               |
                        |                                       |
                        v                                       |
        5.  quotient:   1 / 2 =  0, remainder:   1 % 2 =  1     }
                        .-------/
                        |
                        v
                        0
        6.  Done, since the dividend = 0.

        So, 22 decimal = 10110 binary.
    */

    std::string binaryStr = ""; // Initialize an accumulator string to a blank string
    int dividend = userInput;
    const int divisor = 2;
    while (dividend > 0)
    {
        // calculate quotient
        // calculate remainder

        // Based on the remainder, prepend the correct bit to the accumulator string.
        // Prepending (instead of appending) means the remainder calculated
        // last will come first in the final string.

        // Update dividend for next loop iteration
    }
>The only other thing I would add is to store a copy of num so that you could write it out as the original decimal number at the end - but that's a trivial matter.
How do I do that Lastchance?

Booradley60 I don't think I've learned about const int divisors or binaryStr yet so Idk if I can use them.

http://cpp.sh/4mxid
there are a few problems with this run it to see.
Last edited on
>The only other thing I would add is to store a copy of num so that you could write it out as the original decimal number at the end - but that's a trivial matter.
How do I do that Lastchance?


int numCopy = num;

Ahem!
Sanku.

Now what about the rest of my problems
This is one of them: http://cpp.sh/76eai

The other without the problems: http://cpp.sh/5lshh
Last edited on
dumdumFlame wrote:
Now what about the rest of my problems


Whisky probably helps.
Pages: 123