1

I am writing a c++ program where the program takes the t test cases as input and asks the binary input t times, and after that displays the output. I tried to code but for 1st test case it displays right output in decimal format but for further test cases its not displaying correct output result.

#include<iostream>
#include<cmath>
using namespace std;

int main() {   
    long int num;
    int  r=0,i=0,t,dec=0;
    cin>>t;
    while(t--) {
        cin>>num;

        while (num!=0) {
            r = num% 10;
            num /= 10;
            dec += r * pow(2, i);
            ++i;
        }
        cout<<dec<<"\n"; 
    }
    return 0;
}

This code if run for lets say 2 test cases , lets say first one is 101 , it displays 5 which is fine but on the second input , lets say 111 , it displays output 61. I am not sure where I am getting it wrong.

selbie
  • 100,020
  • 15
  • 103
  • 173
  • Have you tried single stepping through your code with a debugger yet? If not try that first and check where a value starts to differ from what you expect. Debugging is a skill that you will need a lot so best start learning about it today :) – Pepijn Kramer Dec 18 '21 at 05:56
  • 1
    I think the issue might be with the `dec` variable not getting reset back to zero in the `while(t--)` loop. – kite Dec 18 '21 at 05:57
  • 1
    never use `r * pow(2, i)`. Use `r << i` instead – phuclv Dec 18 '21 at 06:09
  • @phuclv r * pow(2, i) is being used for mathematical calculation. What it has to do with r< – Aviral Mishra Dec 18 '21 at 16:53
  • 2
    @AviralMishra it's the shift operator and is one of the most basic things that you need to learn first when learning a programming language. Read a book first [The Definitive C++ Book Guide and List](https://stackoverflow.com/q/388242/995714). Using `pow` for integer power is not only hundreds of times slower but may also produce incorrect results: [Why does pow(5,2) become 24?](https://stackoverflow.com/q/22264236/995714), [Why pow(10,5) = 9,999](https://stackoverflow.com/q/9704195/995714), – phuclv Dec 18 '21 at 16:59

3 Answers3

1

You initialize i, dec outside the outer while loop. Initialize them to 0 inside the outer while loop and it works:

#include <iostream>
#include <cmath>
using namespace std;

int main()
{   
    int t;
    cin >> t;
    
    while(t--)
    {
        int num, r, dec = 0, i = 0;
        cin >> num;

        while (num != 0) {
            r = num % 10;
            num /= 10;
            dec += r * pow(2, i);
            //cout << r << " " << num << " " << i << " " << dec << endl;
            ++i;
        }
        cout << dec << "\n"; 
    }
    return 0;
}
kiner_shah
  • 3,939
  • 7
  • 23
  • 37
1

There is C function strtoull, which is doing the job

Example:

cat bin2dec.cpp 
#include <iostream> 
#include <string>
#include <cstdlib>

using namespace std;

int main() {   
    string num;
    int  t;
    cin>>t;
    while(t--) {
        cin>>num;
        auto dec = strtoull(num.c_str(), NULL, 2);
        cout << dec << endl;
    }
    return 0;
}
g++ -O2 -o bin2dec bin2dec.cpp
2
111
7
100000000000
2048
g++ --version | head -1
g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0
1

While you can use the division and remainder method, C++ provides std::bitset and the string conversion std::stoul, std::stoull that can automate the conversion for you.

The following example loops prompting the user for input of a binary value and converts the value to unsigned long so long as the binary digits entered are 64 or less. Simply press Enter without entering a value to end the program:

#include <iostream>
#include <string>
#include <bitset>

int main() {
  
  for (;;) {                    /* loop continually */
    std::string input{};        /* binary input from user */
    unsigned long value = 0;    /* value to hold conversion to ulong */
    
    /* prompt for input, read/validate input */
    std::cout << "\nenter a binary value: ";
    if (!getline(std::cin, input) || input.size() == 0) {
      break;
    }
    
    if (input.size() > 64) {  /* validate 64 binary digits or less */
      std::cerr << "error: input exceeds 64-bit conversion limit.\n";
      continue;
    }
    
    value = std::bitset<64>(input).to_ulong();    /* convert to ulong */
    std::cout << input << ": " << value << '\n';  /* output result */
  }
}

Note: you would also want to validate the user has entered only '0's and '1's which you can do simply with std::basic_string::find_first_not_of, e.g.

    if (input.find_first_not_of("01") != std::string::npos) {
      std::cerr << "error: invalid input not '0' and '1'\n";
      continue;
    }

(simply add the if statement before the conversion and assignment to value)

Example Use/Output

./bin/bitset_to_ulong

enter a binary value: 1010
1010: 10

enter a binary value: 10000000
10000000: 128

enter a binary value: 1111
1111: 15

enter a binary value: 1234
error: invalid input not '0' and '1'

enter a binary value:

Just an alternative way of doing the same that C++ has provided a convenient way to do in C++11 and forward.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85