1

Consider the following code:

int t,n;
    cin>>t;
    while(t--)
    {
        cin>>n;
        int num,i,ct=0;
        vector<int> summ;
        i=0;
        while(n)
        {
           if(n%10)
           {
               cout<<(n%10)*pow(10,i)<<" ";
               summ.push_back((n%10)*pow(10,i));    ct++;
           }
           i++;
           n=n/10;
        }
        cout<<'\n'<<ct<<'\n';
        for(i=0;i<summ.size();i++)
        {
            cout<<summ[i]<<" ";
        }
        cout<<'\n';
    }

If I give the following input:

1
555

The output produced is 5 50 500 3 5 50 499.

I don't understand why the numbers change on push_back().

Can someone please explain why this is happening?

  • I tried to replicate this issue and was un-successful. https://godbolt.org/z/fFTCVP – Rietty Jun 13 '20 at 18:50
  • The output I got is `5 50 500 3 5 50 500` https://onlinegdb.com/BysVlsM6U – Tony Tannous Jun 13 '20 at 18:51
  • *"Can someone please explain why this is happening? "* -- in the interest of fairness and sharing the burden here, could you please explain what your code is supposed to do? – JaMiT Jun 13 '20 at 20:02
  • I have been able to reproduce `5 50 500 3 5 50 499` on `GNU GCC` 32-bit Windows. The difference appears to be due to rounding, as setting `summ` as vector rather than vector gives the last integer as 500. – Guy Keogh Jun 14 '20 at 00:37

2 Answers2

2

The issue is with the use of pow. You should be storing the result as either a float or a double, as storing directly into an int is causing the imprecision. This seemingly strange behaviour is well known. This behaviour appears to vary depending on your compiler.

To correct this, change your vector<int> summ to vector<float> summ or double. Alternatively, create a temporary float or double variable which is then placed into the vector after the calculation is done.

Guy Keogh
  • 549
  • 2
  • 5
  • 15
1

In the line:

    cout << (n % 10) * pow(10, i) << " ";

you are printing a double value: the integer (n % 10) is converted to a double because the pow() function returns a double.

However, in the line:

    summ.push_back((n % 10) * pow(10, i));

the calculated value (also a double) is truncated to an int before being placed in the vector, because you have declared it to be a std::vector<int>.

So, you may get an error (very occasionally) if the calculated double is even minutely less than the expected 'integral' value. (See: Strange behaviour of the pow function.) Printing the calculated values to full precision will show you if this is, in fact, the case:

    cout << std::setprecision(20) << std::fixed << (n % 10) * pow(10, i) << " ";

A 'quick fix' in this case would be to add 0.5 to the calculated value before it is truncated and pushed:

    summ.push_back((n % 10) * pow(10, i) + 0.5);
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83