简体   繁体   中英

conversion between signed and unsigned in C++

Consider the following C++ code:

#include <cstdio>

using namespace std;

int main()
{
    int ia = -5;
    unsigned int uia = ia;
    char ca = -5;
    unsigned char uca = ca;

    printf("%d\n", (ia == uia));
    printf("%d\n", (ca == uca));

    return 0;
}

The output is

1
0

I don't understand what's the difference between int and char while casting from signed to unsigned ?

Could you please enlighten me?

They both behave the same when converting from signed to unsigned. What behaves differently is the == comparison. It behaves as expected for the int/unsigned, but when you compare two smaller types, they both get promoted to int first. So what happens is that the unsigned 8-bit representation of -5 and -5 both get promoted to int and then get compared. These are obviously different and fail the comparison.

ok, the actual reason for this inconsistent behavior is the underlying promoting of char and unsigned. I'd like to explain this more specificcally.

first, when compaire with a int and an unsigned int variable, their types do not matter because no matter what types they are, their have the same binary-representation in memory, that is what == operator cares.

Whereas when == applies to a char and an unsigned char varialbes, they will firstly expand to the corresponding 32-bit integer type, and how they got expaneded is the key of the inconsistency. Since ca is a char, it will be extended with the sign-bit (via MOVSX) while uca will be extended only with padding 0 (via MOVZX). Thus, they now have inconstent binary-representation.

The assembly code tells this truth.

    int b1 = ia == uia;
000613E5  mov         eax,dword ptr [ia]  
000613E8  xor         ecx,ecx  
000613EA  cmp         eax,dword ptr [uia]  
000613ED  sete        cl  
000613F0  mov         dword ptr [b1],ecx  
    int b2 = ca == uca;
000613F3  movsx       eax,byte ptr [ca]  
000613F7  movzx       ecx,byte ptr [uca]  
000613FB  xor         edx,edx  
000613FD  cmp         eax,ecx  
000613FF  sete        dl  
00061402  mov         dword ptr [b2],edx 

a signed type can be negative aswell as postive. while unsigned are higher in value but can not go negative.

so respectively an unsigned int's max value is 4,294,967,296. and its minimum is 0.

while a signed int's range is -2,147,483,648 to 2,147,483,648.

i hope this helps you understand the difference between signed and unsigned types.

this feature can come in handy when you want to avoid a value being negative. such as a refrence into an array. or if you need only positive large values and no negatives. to save you needing to go up to a long.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM