Things Inside Conversion Between Types in C++
One day, I’m curious about what really happens when converting variables to different types in C++? So I write the following program to find the truth. If you’re boring with program, jump to the conclusion part.
Program to find the truth
#include<iostream>
using namespace std;
//
typedef unsigned char byte;
typedef signed char sbyte;
typedef unsigned int dword;
typedef signed int sdword;
//
enum MyType{TYPE_UNKNOW,TYPE_BYTE,TYPE_SBYTE,TYPE_DWORD,TYPE_SDWORD};
template<class T>
MyType getType(const T t){return TYPE_UNKNOW;}
MyType getType(const dword t){return TYPE_DWORD;}
MyType getType(const sdword t){return TYPE_SDWORD;}
MyType getType(const byte t){return TYPE_BYTE;}
MyType getType(const sbyte t){return TYPE_SBYTE;}
template <class T>
const char *getTypeName(const T t){
switch(getType(t)){
default:
case TYPE_UNKNOW:
return "Unknow";
case TYPE_BYTE:
return "Unsigned Byte";
case TYPE_SBYTE:
return "Signed Byte\t";
case TYPE_DWORD:
return "Unsigned Double Word";
case TYPE_SDWORD:
return "Signed Double Word";
};
}
template<class T>
bool getByte(const T b,int i){
unsigned long k=1;
k<<=i;
return (b&k)==k;
//return ((b>>i)&0x1)==0x1;
}
//
template <class T>
inline void _printB(const T t,int numBits){
//like a memory [high ... low]
//print from high address bits, to low address bits.
for(int i=numBits-1;i>=0;i--){
cout<<getByte(t,i);
}
}
template <class T>
inline void printB(const T t,int numBits=-1){
if(numBits==-1){
if(getType(t)==TYPE_BYTE||getType(t)==TYPE_SBYTE){
numBits=8;
}else{
numBits=32;
}
}
_printB(t,numBits);
}
template<class T>
void printT(const T t){
if(getType(t)==TYPE_BYTE||getType(t)==TYPE_SBYTE){
cout<<(int)t;
}else{
cout<<t;
}
}
//
template<class T>
void testType(T t){
#define print(m) cout<<#m"\t";printT(m);cout<<"\t";printB(m);cout<<endl;
byte b=t;
sbyte sb=t;
dword dw=t;
sdword sdw=t;
#define ToWhat(v) cout<<"To "<<getTypeName(v)<<"\t";print(v);
ToWhat(b);
ToWhat(sb);
ToWhat(dw);
ToWhat(sdw);
cout<<endl;
}
void testAllType(){
#define ShowTest(v,cmd) cmd;\
cout<<"After run command:"#cmd""<<endl;\
cout<<"From "<<getTypeName(v)<<"\t";print(v);\
cout<<"---"<<endl;\
testType(v);cout<<endl;
#define ShowTests(v) \
ShowTest(v,v=128);\
ShowTest(v,v=127);\
ShowTest(v,v++);\
ShowTest(v,v++);\
ShowTest(v,v=-1);\
ShowTest(v,v--);\
ShowTest(v,v=0xffffff00+64);\
byte b;
sbyte sb;
dword dw;
sdword sdw;
//
ShowTests(b);
ShowTests(sb);
ShowTests(dw);
ShowTests(sdw);
//
}
int main(){
testAllType();
return 0;
}
#The result of program.
After run command:b=128
From Unsigned Byte b 128 10000000
---
To Unsigned Byte b 128 10000000
To Signed Byte sb -128 10000000
To Unsigned Double Word dw 128 00000000000000000000000010000000
To Signed Double Word sdw 128 00000000000000000000000010000000
After run command:b=127
From Unsigned Byte b 127 01111111
---
To Unsigned Byte b 127 01111111
To Signed Byte sb 127 01111111
To Unsigned Double Word dw 127 00000000000000000000000001111111
To Signed Double Word sdw 127 00000000000000000000000001111111
After run command:b++
From Unsigned Byte b 128 10000000
---
To Unsigned Byte b 128 10000000
To Signed Byte sb -128 10000000
To Unsigned Double Word dw 128 00000000000000000000000010000000
To Signed Double Word sdw 128 00000000000000000000000010000000
After run command:b++
From Unsigned Byte b 129 10000001
---
To Unsigned Byte b 129 10000001
To Signed Byte sb -127 10000001
To Unsigned Double Word dw 129 00000000000000000000000010000001
To Signed Double Word sdw 129 00000000000000000000000010000001
After run command:b=-1
From Unsigned Byte b 255 11111111
---
To Unsigned Byte b 255 11111111
To Signed Byte sb -1 11111111
To Unsigned Double Word dw 255 00000000000000000000000011111111
To Signed Double Word sdw 255 00000000000000000000000011111111
After run command:b--
From Unsigned Byte b 254 11111110
---
To Unsigned Byte b 254 11111110
To Signed Byte sb -2 11111110
To Unsigned Double Word dw 254 00000000000000000000000011111110
To Signed Double Word sdw 254 00000000000000000000000011111110
After run command:b=0xffffff00+64
From Unsigned Byte b 64 01000000
---
To Unsigned Byte b 64 01000000
To Signed Byte sb 64 01000000
To Unsigned Double Word dw 64 00000000000000000000000001000000
To Signed Double Word sdw 64 00000000000000000000000001000000
After run command:sb=128
From Signed Byte sb -128 10000000
---
To Unsigned Byte b 128 10000000
To Signed Byte sb -128 10000000
To Unsigned Double Word dw 4294967168 11111111111111111111111110000000
To Signed Double Word sdw -128 11111111111111111111111110000000
After run command:sb=127
From Signed Byte sb 127 01111111
---
To Unsigned Byte b 127 01111111
To Signed Byte sb 127 01111111
To Unsigned Double Word dw 127 00000000000000000000000001111111
To Signed Double Word sdw 127 00000000000000000000000001111111
After run command:sb++
From Signed Byte sb -128 10000000
---
To Unsigned Byte b 128 10000000
To Signed Byte sb -128 10000000
To Unsigned Double Word dw 4294967168 11111111111111111111111110000000
To Signed Double Word sdw -128 11111111111111111111111110000000
After run command:sb++
From Signed Byte sb -127 10000001
---
To Unsigned Byte b 129 10000001
To Signed Byte sb -127 10000001
To Unsigned Double Word dw 4294967169 11111111111111111111111110000001
To Signed Double Word sdw -127 11111111111111111111111110000001
After run command:sb=-1
From Signed Byte sb -1 11111111
---
To Unsigned Byte b 255 11111111
To Signed Byte sb -1 11111111
To Unsigned Double Word dw 4294967295 11111111111111111111111111111111
To Signed Double Word sdw -1 11111111111111111111111111111111
After run command:sb--
From Signed Byte sb -2 11111110
---
To Unsigned Byte b 254 11111110
To Signed Byte sb -2 11111110
To Unsigned Double Word dw 4294967294 11111111111111111111111111111110
To Signed Double Word sdw -2 11111111111111111111111111111110
After run command:sb=0xffffff00+64
From Signed Byte sb 64 01000000
---
To Unsigned Byte b 64 01000000
To Signed Byte sb 64 01000000
To Unsigned Double Word dw 64 00000000000000000000000001000000
To Signed Double Word sdw 64 00000000000000000000000001000000
After run command:dw=128
From Unsigned Double Word dw 128 00000000000000000000000010000000
---
To Unsigned Byte b 128 10000000
To Signed Byte sb -128 10000000
To Unsigned Double Word dw 128 00000000000000000000000010000000
To Signed Double Word sdw 128 00000000000000000000000010000000
After run command:dw=127
From Unsigned Double Word dw 127 00000000000000000000000001111111
---
To Unsigned Byte b 127 01111111
To Signed Byte sb 127 01111111
To Unsigned Double Word dw 127 00000000000000000000000001111111
To Signed Double Word sdw 127 00000000000000000000000001111111
After run command:dw++
From Unsigned Double Word dw 128 00000000000000000000000010000000
---
To Unsigned Byte b 128 10000000
To Signed Byte sb -128 10000000
To Unsigned Double Word dw 128 00000000000000000000000010000000
To Signed Double Word sdw 128 00000000000000000000000010000000
After run command:dw++
From Unsigned Double Word dw 129 00000000000000000000000010000001
---
To Unsigned Byte b 129 10000001
To Signed Byte sb -127 10000001
To Unsigned Double Word dw 129 00000000000000000000000010000001
To Signed Double Word sdw 129 00000000000000000000000010000001
After run command:dw=-1
From Unsigned Double Word dw 4294967295 11111111111111111111111111111111
---
To Unsigned Byte b 255 11111111
To Signed Byte sb -1 11111111
To Unsigned Double Word dw 4294967295 11111111111111111111111111111111
To Signed Double Word sdw -1 11111111111111111111111111111111
After run command:dw--
From Unsigned Double Word dw 4294967294 11111111111111111111111111111110
---
To Unsigned Byte b 254 11111110
To Signed Byte sb -2 11111110
To Unsigned Double Word dw 4294967294 11111111111111111111111111111110
To Signed Double Word sdw -2 11111111111111111111111111111110
After run command:dw=0xffffff00+64
From Unsigned Double Word dw 4294967104 11111111111111111111111101000000
---
To Unsigned Byte b 64 01000000
To Signed Byte sb 64 01000000
To Unsigned Double Word dw 4294967104 11111111111111111111111101000000
To Signed Double Word sdw -192 11111111111111111111111101000000
After run command:sdw=128
From Signed Double Word sdw 128 00000000000000000000000010000000
---
To Unsigned Byte b 128 10000000
To Signed Byte sb -128 10000000
To Unsigned Double Word dw 128 00000000000000000000000010000000
To Signed Double Word sdw 128 00000000000000000000000010000000
After run command:sdw=127
From Signed Double Word sdw 127 00000000000000000000000001111111
---
To Unsigned Byte b 127 01111111
To Signed Byte sb 127 01111111
To Unsigned Double Word dw 127 00000000000000000000000001111111
To Signed Double Word sdw 127 00000000000000000000000001111111
After run command:sdw++
From Signed Double Word sdw 128 00000000000000000000000010000000
---
To Unsigned Byte b 128 10000000
To Signed Byte sb -128 10000000
To Unsigned Double Word dw 128 00000000000000000000000010000000
To Signed Double Word sdw 128 00000000000000000000000010000000
After run command:sdw++
From Signed Double Word sdw 129 00000000000000000000000010000001
---
To Unsigned Byte b 129 10000001
To Signed Byte sb -127 10000001
To Unsigned Double Word dw 129 00000000000000000000000010000001
To Signed Double Word sdw 129 00000000000000000000000010000001
After run command:sdw=-1
From Signed Double Word sdw -1 11111111111111111111111111111111
---
To Unsigned Byte b 255 11111111
To Signed Byte sb -1 11111111
To Unsigned Double Word dw 4294967295 11111111111111111111111111111111
To Signed Double Word sdw -1 11111111111111111111111111111111
After run command:sdw--
From Signed Double Word sdw -2 11111111111111111111111111111110
---
To Unsigned Byte b 254 11111110
To Signed Byte sb -2 11111110
To Unsigned Double Word dw 4294967294 11111111111111111111111111111110
To Signed Double Word sdw -2 11111111111111111111111111111110
After run command:sdw=0xffffff00+64
From Signed Double Word sdw -192 11111111111111111111111101000000
---
To Unsigned Byte b 64 01000000
To Signed Byte sb 64 01000000
To Unsigned Double Word dw 4294967104 11111111111111111111111101000000
To Signed Double Word sdw -192 11111111111111111111111101000000
Observation from the result of program.
-
When a signed varialbe Var is converted to a bigger-size variable NewVar, the new expanding high bits are filled with the same bit as the highest bit of Var, i.e. if Var is positive, NewVar is filled with 0, while if Var is negative, NewVar is filled with 1.
-
When a unsigned variable is converted to a bigger-size variable, the expanding bits are filled with 0.
-
When a variable is converted to a less-size variable, cut the high bits directly.
Conclusion
In a nutshell, to expand a Var to a bigger size, fill with 0 if Var is a unsigned or Var is postive, otherwise 1.
Leave a Comment
Your email address will not be published. Required fields are marked *