I am solving a leetcode problem, which the output need to be a binary number without abundant digits.
I have the decimal number and I was trying to use bitset to do the conversion.
I wrote a function to return the number of digit given the number n:
int digitNum (int n){
int digit = 0;
while(n!=0){
n/=2;
digit++;
}
return digit;
}
But when I called it,
int digit = digitNum(res);
result = bitset<digit>(res).to_string();
the digit needs to be a constant. I read the boost::bitset, and I don't see how I can use a dynamic bitset to fix my problem.
http://www.boost.org/doc/libs/1_63_0/libs/dynamic_bitset/dynamic_bitset.html
because it's defining each bit by hand. It doesn't convert to binary anymore.
bitset is a template. Any option in <> is generated at compile-time, so they can't take an input from a variable at runtime to choose template parameters. you can use a loop much like your existing one to do the same job as bitset:
string numToBits(int number)
{
if (number == 0)
return "0";
string temp;
int n = (number > 0) ? number : - number;
while (n > 0)
{
temp = string((n & 1) ? "1" : "0") + temp;
n = n / 2;
}
if(number < 0)
temp = "-" + temp;
return temp;
}
Related
I was asked to write code for converting a decimal to its binary form. I have tried several different ways but doesn't gives me the order i need. So i am currently stuck on how to proceed.
I have tried by normally finding the binary comparison but it gives me in the incorrect order, lets say the correct order is 1001100, i just get 0011001. and i have no way of changing the order. I am not allowed to use any other library other than iostream, cmath and string. I am now trying to simply find the conversion using the exponent 2^exponent.
This is what i currently have:
int num, exp,rem;
string biNum;
cout<<"Enter decimal number: "<<endl;
cin>>num;
for (exp = 0; pow(2, exp) < num; exp++) {
}
while (num > 0) {
rem = num % (int) pow(2, exp);
if (rem != 0) {
biNum = biNum + '1';
} else {
biNum = biNum + '0';
}
exp--;
}
cout<<biNum;
return 0;
}
I am currently receiving no result at all.
Here is an example that collects the bits in Least Significant Bit (LSB):
//...
while (num > 0)
{
const char bit = '0' + (num & 1);
biNum += bit;
num = num >> 1;
}
Explanation
The loop continues until the num variable is zero. There is no point in adding extra zeros unless you really want them.
The (num & 1) expression returns 1 if the bit is 1, or 0 if the bit is 0.
This is then added to the character 0 to produce either '0' or '1'.
The variable is declared as const since it won't be modified after declaration (definition).
The newly created character is appended to the bit string.
Finally, the num is right shifted by one bit (because that bit was already processed).
There are many other ways to collect the bits in Most Significant Bit (MSB) order. Those ways are left for the OP and the reader. :-)
Here you go. This outputs the bits in the right order:
#include <iostream>
#include <string>
int main ()
{
unsigned num;
std::string biNum;
std::cin >> num;
while (num)
{
char bit = (num & 1) + '0';
biNum.insert (biNum.cbegin (), bit);
num >>= 1;
}
std::cout << biNum;
return 0;
}
Live demo
You can use a recursive function to print the result in reverse order, avoiding using a container/array, like so:
void to_binary(int num) {
int rem = num % 2;
num = (num - rem) / 2;
if (num < 2){
std::cout << rem << num;
return;
}
to_binary(num);
std::cout << rem;
}
int main()
{
to_binary(100);
}
I am using a Constructor to take an unsigned int as an argument, break it into digits and assign the appropriate true and false values to a vector object. But the problem is that, my poor logic assigns the values in reverse order as the last digit is separated first and so on. The Code I have written is:
vector<bool> _bits;
uBinary(unsigned int num){
int i = 1;
while(num > 0)
{
int d = num%10;
num /= 10;
_bits.resize(i++);
if(d == 1)
{
_bits[_bits.size() - 1] = true;
}
else if(d==0)
{
_bits[_bits.size() - 1] = false;
}
}
}
For example: if argument 10011 is passed to the function uBinary() the vector object will be assigned the values in this order 11001 or true,true,false,false,true which is reversed.
All I need to do here is that, I want to assign the values without reversing the order and I don't want to use another loop for this purpose.
One way is to start at the highest possible digit (unsigned int can only hold values up to 4294967295 on most platforms) and ignore leading zeros until the first actual digit is found:
for (uint32_t divisor = 1000000000; divisor != 0; divisor /= 10) {
uint32_t digit = num / divisor % 10;
if (digit == 0 && _bits.size() == 0 && divisor != 1)
continue; // ignore leading zeros
_bits.push_back(digit == 1);
}
But finding the digits in reverse and then simply reversing them is much simpler (and at least as efficient):
do {
_bits.push_back(num % 10 == 1);
num /= 10;
} while (num != 0);
std::reverse(_bits.begin(), _bits.end());
One way you can do the reversing with another loop or std::reverse is to use recursion. With recursion you can walk down the int until you hit the last digit and then you add the values to the vector as the calls return. That would look like
void uBinary(unsigned int num)
{
if (num == 0)
return;
uBinary(num / 10);
_bits.push_back(num % 10 ? true : false);
}
Which you can see working with
int main()
{
uBinary(10110);
for (auto e : _bits)
std::cout << e << " ";
}
Live Example
Do note that it is advisable not to use leading underscores in variables names. Some names are reserved for the implementation and if you use one it is undefined behavior. For a full explanation of underscores in names see: What are the rules about using an underscore in a C++ identifier?
This is what I have:
string decimal_to_binary(int n){
string result = "";
while(n > 0){
result = string(1, (char) (n%2 + 48)) + result;
n = n/2;
}
return result; }
This works, but it doesn't work if I put a negative number, any help?
Just
#include <bitset>
Then use bitset and to_string to convert from int to string
std::cout << std::bitset<sizeof(n)*8>(n).to_string();
It works for negative numbers too.
Well I would recommend calling a separate function for negative numbers. Given that, for example, -1 and 255 will both return 11111111. Converting from the positive to the negative would be easiest instead of changing the logic entirely to handle both.
Going from the positive binary to the negative is just running XOR and adding 1.
You can modify your code like this for a quick fix.
string decimal_to_binary(int n){
if (n<0){ // check if negative and alter the number
n = 256 + n;
}
string result = "";
while(n > 0){
result = string(1, (char) (n%2 + 48)) + result;
n = n/2;
}
return result;
}
This works, but it doesn't work if I put a negative number, any help?
Check whether the number is negative. If so, call the function again with -n and return the concatenated result.
You also need to add a clause to check against 0 unless you want to return an empty string when the input is 0.
std::string decimal_to_binary(int n){
if ( n < 0 )
{
return std::string("-") + decimal_to_binary(-n);
}
if ( n == 0 )
{
return std::string("0");
}
std::string result = "";
while(n > 0){
result = std::string(1, (char) (n%2 + 48)) + result;
n = n/2;
}
return result;
}
Is there any technique for finding the reverse when there are zeros at the end.
While following the algorithm of %10 technique the result is 52. And the 0's are missing.
I have got the reverse by just printing the reminders (with 0's). But I am not satisfied as I wish to display the answer as the value in a variable.
Kindly tell me is there any technique to store a value 005 to a variable and also to display 005 (please don't use String or Character or array).
Numbers are stored as binary 0 and 1 and so they always have leading 0's which are chopped off. e.g. a 64-bit integer has 64-bit bits, always and when it is printed these leading 0's are dropped.
You need to know how many leading zeros you want to keep and only use that many when you print. i.e. you can record how many leading zeros there were in a normal number without encoding it e.g. by adding a 1 at the start. i.e. 0052 is recorded as 10052 and you skip the first digit when you print.
If you need to store a single value you can do the following. I use do/while so that 0 becomes 10 and is printed as 0. The number 0 is the one place where not all leading zeros are dropped (as it would be empty otherwise)
This appears to be the solution you want and it should be basically the same in C or C++
static long reverse(long num) {
long rev = 1; // the 1 marks the start of the number.
do {
rev = rev * 10 + num % 10;
num /= 10;
} while(num != 0);
return rev;
}
// make the reversed number printable.
static String toStringReversed(long num) {
return Long.toString(num).substring(1);
}
long l = reverse(2500); // l = 10052
An alternative is to print the digits as you go and thus not need to store it.
e.g.
static void printReverse(long l) {
do {
System.out.print(l % 10);
l /= 10;
} while(l != 0);
}
or you can have the input record the number of digits.
static void printReverse(long l, int digits) {
for(int i = 0; i < digits; i++) {
System.out.print(l % 10);
l /= 10;
}
}
// prints leading zero backwards as well
printReverse(2500, 6); // original number is 002500
prints
005200
You cannot represent an integer with leading zeros as a single integer variable, that information is simply not part of the way bits are allocated in an integer. You must use something larger, i.e. a string or an array of individual (small integer) digits.
You can't store them in a simple integer variable because in binary format
00101 is same as 000101 which is same as 101 which only results into 5. The convertion between a decimal number and binary numbers don't consider leading zeroes so it is not possible to store leading zeroes with the same integer variable.
You can print it but you can't store the leading zeroes unless you use array of ints...
int num = 500;
while(num > 0)
{
System.out.print(num%10);
num = num/10;
}
Alternatively you can store the count of leading zeroes as a separate entity and combine them when ever you need to use. As shown below.
int num = 12030;
boolean leading=true;
int leadingCounter = 0;
int rev = 0;
while(num > 0)
{
int r = num%10;
if(r == 0 && leading == true)
leadingCounter++;
else
leading = false;
rev = rev*10 + r;
num = num/10;
}
for(int i = 1; i <= leadingCounter ; i++)
System.out.print("0");
System.out.println(rev);
I think the accepted answer is a good one, in that it both refutes the parts of the question that are wrong and also offers a solution that will work. However, the code there is all Java, and it doesn't expose the prettiest API. Here's a C++ version that based on the code from the accepted answer.
(Ha ha for all my talk, my answer didn't reverse the string! Best day ever!)
After going back to school and getting a degree, I came up with this answer: it has the makes the somewhat dubious claim of "not using strings" or converting any values to string. Can't avoid characters, of course, since we are printing the value in the end.
#include <ostream>
#include <iostream>
class ReverseLong {
public:
ReverseLong(long value) {
long num = value;
bool leading = true;
this->value = 0;
this->leading_zeros = 0;
while (num != 0) {
int digit = num % 10;
num = num / 10;
if (leading && digit == 0) {
this->leading_zeros += 1;
} else {
this->value = this->value * 10 + digit;
leading = false;
}
}
};
friend std::ostream & operator<<(std::ostream& out, ReverseLong const & r);
private:
long value;
int leading_zeros;
};
std::ostream & operator<<(std::ostream& out, ReverseLong const & r) {
for (int i =0; i < r.leading_zeros; i++) {
out << 0;
}
out << r.value;
return out;
};
int main () {
ReverseLong f = ReverseLong(2500); // also works with numbers like "0"!
std::cout << f << std::endl; / prints 0052
};
convert a positive integer number in C++ (0 to 2,147,483,647) to a 32 bit binary and display.
I want do it in traditional "mathematical" way (rather than use bitset or use vector *.pushback* or recursive function or some thing special in C++...), (one reason is so that you can implement it in different languages, well maybe)
So I go ahead and implement a simple program like this:
#include <iostream>
using namespace std;
int main()
{
int dec,rem,i=1,sum=0;
cout << "Enter the decimal to be converted: ";
cin>>dec;
do
{
rem=dec%2;
sum=sum + (i*rem);
dec=dec/2;
i=i*10;
} while(dec>0);
cout <<"The binary of the given number is: " << sum << endl;
system("pause");
return 0;
}
Problem is when you input a large number such as 9999, result will be a negative or some weird number because sum is integer and it can't handle more than its max range, so you know that a 32 bit binary will have 32 digits so is it too big for any number type in C++?. Any suggestions here and about display 32 bit number as question required?
What you get in sum as a result is hardly usable for anything but printing. It's a decimal number which just looks like a binary.
If the decimal-binary conversion is not an end in itself, note that numbers in computer memory are already represented in binary (and it's not the property of C++), and the only thing you need is a way to print it. One of the possible ways is as follows:
int size = 0;
for (int tmp = dec; tmp; tmp >>= 1)
size++;
for (int i = size - 1; i >= 0; --i)
cout << ((dec >> i) & 1);
Another variant using a character array:
char repr[33] = { 0 };
int size = 0;
for (int tmp = dec; tmp; tmp >>= 1)
size++;
for (int i = 0; i < size; ++i)
repr[i] = ((dec >> (size - i - 1)) & 1) ? '1' : '0';
cout << repr << endl;
Note that both variants don't work if dec is negative.
You have a number and want its binary representation, i.e, a string. So, use a string, not an numeric type, to store your result.
Using a for-loop, and a predefined array of zero-chars:
#include <iostream>
using namespace std;
int main()
{
int dec;
cout << "Enter the decimal to be converted: ";
cin >> dec;
char bin32[] = "00000000000000000000000000000000";
for (int pos = 31; pos >= 0; --pos)
{
if (dec % 2)
bin32[pos] = '1';
dec /= 2;
}
cout << "The binary of the given number is: " << bin32 << endl;
}
For performance reasons, you may prematurely suspend the for loop:
for (int pos = 31; pos >= 0 && dec; --pos)
Note, that in C++, you can treat an integer as a boolean - everything != 0 is considered true.
You could use an unsigned integer type. However, even with a larger type you will eventually run out of space to store binary representations. You'd probably be better off storing them in a string.
As others have pointed out, you need to generate the results in a
string. The classic way to do this (which works for any base between 2 and 36) is:
std::string
toString( unsigned n, int precision, unsigned base )
{
assert( base >= 2 && base <= 36 );
static char const digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::string retval;
while ( n != 0 ) {
retval += digits[ n % base ];
n /= base;
}
while ( retval.size() < precision ) {
retval += ' ';
}
std::reverse( retval.begin(), retval.end() );
return retval;
}
You can then display it.
Recursion. In pseudocode:
function toBinary(integer num)
if (num < 2)
then
print(num)
else
toBinary(num DIV 2)
print(num MOD 2)
endif
endfunction
This does not handle leading zeros or negative numbers. The recursion stack is used to reverse the binary bits into the standard order.
Just write:
long int dec,rem,i=1,sum=0
Instead of:
int dec,rem,i=1,sum=0;
That should solve the problem.