Ваше значение 0x80, хранящееся в символе, является подписанным количеством. Когда вы преобразуете его в более широкий тип, значение расширяется со знаком, чтобы сохранить то же значение, что и у более крупного типа.
Измените тип char
в первой строке на unsigned char
, и вы не получите расширение знака.
Чтобы упростить то, что происходит в вашем случае, запустите:
char c = 0x80
unsigned long l = c
cout << l << endl;
Вы получите этот вывод:
18446744073709551488
, что равно -128 как 64-разрядное целое число (0x80 равно -128 как 8-разрядное целое число).