Я узнал о 2 Complement
и неподписанном и подписанном int. Поэтому я решил проверить свои знания, насколько я знаю, что отрицательное число хранится в 2 Complement
так, чтобы сложение и вычитание не имели бы другого алгоритма и схемы были бы простыми.
Теперь, если я пишу
int main()
{
int a = -1 ;
unsigned int b = - 1 ;
printf("%d %u \n %d %u" , a ,a , b, b);
}
Выход будет равен -1 4294967295 -1 4294967295
. Теперь я посмотрел на структуру битов и различные вещи, а затем понял, что -1
в 2 дополнениях 11111111 11111111 11111111 11111111
, поэтому, когда я интерпретирую его с помощью% d, он дает -1
, но когда я интерпретирую использование %u
, он рассматривает его как положительное число и поэтому дает 4294967295
. Я проверил сборку кода
.LC0:
.string "%d %u \n %d %u"
main:
push rbp
mov rbp, rsp
sub rsp, 16
mov DWORD PTR [rbp-4], -1
mov DWORD PTR [rbp-8], -1
mov esi, DWORD PTR [rbp-8]
mov ecx, DWORD PTR [rbp-8]
mov edx, DWORD PTR [rbp-4]
mov eax, DWORD PTR [rbp-4]
mov r8d, esi
mov esi, eax
mov edi, OFFSET FLAT:.LC0
mov eax, 0
call printf
mov eax, 0
leave
ret
Теперь здесь -1
перемещается в регистр как раз в unsigned и signed. То, что я хочу знать, если только имеет смысл переинтерпретация, то почему у нас есть два типа unsigned
и signed
, это строка printf
format %d
и %u
, что имеет значение?
Далее, что действительно происходит, когда я назначаю отрицательное число целому числу без знака (я узнал, что инициализатор преобразует это значение из int
в unsigned int
.), но в коде сборки я этого не видел. Так что же происходит на самом деле?
И как машина знает, когда ей нужно делать 2 Complement
, а когда нет, видит ли она отрицательный знак и выполняет 2 Complement
?
Я прочитал почти каждый вопрос и ответ, вы можете подумать, что этот вопрос дублируется, но я не мог найти удовлетворительного решения.