vintage_Petr_Mitrichev's blog

By vintage_Petr_Mitrichev, history, 5 days ago, In English,

Why such strange behaviour while outputting the difference in sizes of two queues. When i am storing them in a diff variable its showing right answer, while just outputting the difference gives wrong answer.

code

#include<bits/stdc++.h>
using namespace std;
int main()
{
    priority_queue<int , vector<int> , greater<int> > pmin;
    priority_queue<int , vector<int> >pmax;
    pmin.push(5);
    pmin.push(9);
    pmin.push(10);
    pmax.push(1);
    cout << pmax.size() - pmin.size() << endl;
    int diff = pmax.size() - pmin.size();
    cout << diff <<endl;
    return 0 ;
}

**** TO DV : Since downvotes doesn't affects me, but I think this is a very good question whom most of have no idea about the flaw in this. So it would be good if some good answers known to other people.

 
 
 
 
  • Vote: I like it
  • -23
  • Vote: I do not like it

»
5 days ago, # |
  Vote: I like it -8 Vote: I do not like it

anyone can run the code on their compiler and check the strange behaviour of it. why its so.

»
5 days ago, # |
Rev. 3   Vote: I like it +19 Vote: I do not like it

Because a.size() return unsigned int and you get overflow. This is true for all STL container

  • »
    »
    5 days ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    unsigned bit, but why its not happening when i am storing it in diff variable.

    • »
      »
      »
      5 days ago, # ^ |
      Rev. 2   Vote: I like it +4 Vote: I do not like it

      This work: cout << (int)(pmax.size() — pmin.size()) << endl; It has something to do with cast to a larger type

      • »
        »
        »
        »
        5 days ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        ok, so its better to typecast or store it in a variable.

      • »
        »
        »
        »
        5 days ago, # ^ |
          Vote: I like it 0 Vote: I do not like it

        hello, but i don't understand, which case to choose what. do we have to always typecast it, if we are dealing with any kind of stuffs like these ?

»
5 days ago, # |
  Vote: I like it +3 Vote: I do not like it

See here.the overflowed diff in unsigned long long will be equal to the exact signed diff as leftmost bit will be sign bit(you can observe it with 2's complement). Even if it is converted to signed int32 and diff is in int32 range then we can also see it correctly(your code). As leftmost 32 bits of 64 bits will be overflow bit for int32. However if diff is not converted to signed number then we will see garbage value.

  • »
    »
    5 days ago, # ^ |
      Vote: I like it 0 Vote: I do not like it

    ok that overflow part i got, but why overflow is not happening in case when we are typecasting it or storing it in a variable.

    without typecasting why there is problem and how typecasting removes the error.

    • »
      »
      »
      5 days ago, # ^ |
      Rev. 2   Vote: I like it 0 Vote: I do not like it

      Overflow bits are always thrown away. Int64 can't have more than 64 bit. For unsigned the gotten number will be garbage but if converted to signed number then we will see signed value(actually their binary representation will be same) . You can see about signed, unsigned and overflow.

»
5 days ago, # |
Rev. 2   Vote: I like it 0 Vote: I do not like it

A refresher of Digital Systems class:

pmax.size() — pmin.size()

which is: 1 — 3

Since both are unsigned numbers, hence it will be calculated in the machine as:

1 + ( 2's complement of 3)

2's complement of 3 will be 18446744073709551613 (Considering unsigned long long)

Hence answer will be 18446744073709551614

If you store this number in a long long variable then it will become a signed number. Thus bits that correspond to 18446744073709551614 in unsigned long long will be -2 in signed long long.

You can understand it by realizing that the machine has the same system for addition and subtraction, be it signed numbers or unsigned numbers. If you want to understand it properly then you will need to study the whole number representation.

As a good practice, it is better to typecast the operands before doing such operations.

»
5 days ago, # |
  Vote: I like it 0 Vote: I do not like it

Learn about unsigned numbers