My Blog List

Unsigned Int

Int and Unsigned Int

  • No matter what type of data it is, int or unsigned int, it is always stored as a 32 bits binary number in the computer. Thus a int could always convert with a unsisged int. The only problem is whether the convert result is as the same as we expected
  • This problem might be important because the size_t is the unsigned int type which is the return type of size() function. We use size() function very frequently and if we use it in a loop sentence, always a warning appear if you switch on the compiler option. Thus there is always a implicit conversion from int to unsigned int.
  • It could be right if all we talk about the non-negative. However if it is a negative number, problem could appear.
i=i+1;
  • Let's think about this program 
#include<iostream>
#include<string>
using namespace std;
int main(){
    int i=-1;
    unsigned int u=100;
    if(i<u)
        cout<<"-1 < 100";
    else 
        cout<<"-1 > 100";
    return 0;
}

The output is     "-1 > 100".
Is that weird? Yes it is. Because it is the implicit conversion from int to unsigned it. And -1 will be converted to a big num.
  • Actually since both int and unsigned int are the store as a binary number in computer, when conversion executed, it is not the actual conversion. It is just another output method. The bit info stored in memory doesn't change. What changed is how you read and parse this data, treat it as whether a int or a unsigned int. Have a look at following code
  • #include<iostream>
    #include<cmath>
    using namespace std;
    int main(){
        cout<<"2^32="<<(int)pow(2,32)<<endl;
        cout<<"Data type conversion"<<endl;
        cout<<"This is an illustation of how int convert with unsigned int"<<endl;
    //unsigned int is directly represented by binary representation
    //int is stored in two's complement. Thus if a int has n bits, then the bigget one is 2^(n-1)-1, however the smallest one is 2*(n-1) because the positve part uses one to represent the +0 thus the negative part donnot need to represent the -0.
    
        unsigned int u;
        int i;
    
        cout<<"11111...11111"<<endl;
        u=(unsigned int)pow(2,32)-1;
        i=u;
        cout<<"u="<<u<<endl<<"i="<<i<<endl;
    
        cout<<"10000...00000"<<endl;
        u=(unsigned int)pow(2,31);
        i=u;
        cout<<"u="<<u<<endl<<"i="<<i<<endl;
    
        cout<<"00000...00000"<<endl;
        u=(unsigned int)0;
        i=u;
        cout<<"u="<<u<<endl<<"i="<<i<<endl;
        return 0;
    }
    
    
  •  For more details about the two's complement can be found here at wiki
  •  Now we can predict what if we convert a negative int to a unsigned int using the knowledge above
  • #include<iostream>
    #include<cmath>
    using namespace std;
    int main(){
        cout<<"2^32="<<(int)pow(2,32)<<endl;
        cout<<"Data type conversion"<<endl;
        cout<<"This is an illustation of how int convert with unsigned int"<<endl;
    //unsigned int is directly represented by binary representation
    //int is stored in two's complement. Thus if a int has n bits, then the bigget one is 2^(n-1)-1, however the smallest one is 2*(n-1) because the positve part uses one to represent the +0 thus the negative part donnot need to represent the -0.
    
        unsigned int u;
        int i;
    
        cout<<"11111...11111"<<endl;
        u=(unsigned int)pow(2,32)-1;
        i=u;
        cout<<"u="<<u<<endl<<"i="<<i<<endl;
    
        cout<<"10000...00000"<<endl;
        u=(unsigned int)pow(2,31);
        i=u;
        cout<<"u="<<u<<endl<<"i="<<i<<endl;
    
        cout<<"00000...00000"<<endl;
        u=(unsigned int)0;
        i=u;
        cout<<"u="<<u<<endl<<"i="<<i<<endl;
        return 0;
    }
    
    
  • So far we're talking about the uselessness. Now the point I want say is, when ever use size() function or use a unsigned int, do remember to check if it has any operation with a int even worse it has a operation with a negative int.
  • Just think about this code. What will be outputed
  • vector<int> v;
    for(int i=-10;i<v.size();i++)
        cout<<i;
    
  • Now we can step further talk about the overflow. Consider the following code
  • #include<iostream>
    #include<climits>
    using namespace std;
    int main(){
        int i=INT_MAX;
        cout<<i<<endl<<i+1<<endl;
        i=INT_MIN;
        cout<<i<<endl<<i-1<<endl;
        unsigned int u=UINT_MAX;
        cout<<u<<endl<<u+1<<endl;
        return 0;
    }
    
  • Yes,
    • INT_MAX + 1 = INT_MIN
    • INT_MIN - 1 = INT_MAX.
    • UINT_MAX+ 1 = 0. 

No comments:

Post a Comment

Enter you comment