битовое представление unsigned int a = -1

Каково битовое представление unsigned int x =-1;. Можем ли мы присвоить unsigned int отрицательное целое число?

#include<stdio.h> 
int main(){
    unsigned int x = -1; 
    int y = ~0; 
    if(x == y) 
        printf("same"); 
    else
        printf("not same"); 
    return 0;
}

вывод :

такой же

и как это возможно, x без знака

#include<stdio.h> 

int  main()     
{

unsigned int x = -4; 
if (x == -4)
   printf("true");
else 
   printf("FALSE");
}

вывод:

истинный


person pranav prashant    schedule 30.09.2014    source источник
comment
unsigned не может быть отрицательным :) когда вы написали слово unsigned вы не думаете, что оно означает?   -  person Ivan Ivanovich    schedule 30.09.2014
comment
Ответ на ваш вопрос уже есть в вашем примере.   -  person dari    schedule 30.09.2014
comment
я имею в виду, как -1 представлен в двоичной форме. Какая логика, что -1 и 1 одинаковы   -  person pranav prashant    schedule 30.09.2014
comment
-1 всегда UMAX, см. это и это   -  person Shafik Yaghmour    schedule 30.09.2014
comment
@larsmans: язык требует, чтобы (unsigned)(-1) производил UNIT_MAX на всех платформах, независимо от того, используют ли они двойную реализацию или нет.   -  person AnT    schedule 30.09.2014
comment
~0, с другой стороны, дает -1 только в том случае, если реализация использует дополнение до 2 (и для полноты картины ~0 может быть представлением ловушки (в противном случае это отрицательный нуль) для дополнения до 1).   -  person mafso    schedule 01.10.2014


Ответы (3)


Когда значение unsigned int сравнивается со значением int, значение int неявно преобразуется в тип unsigned int. Результат такого преобразования конгруэнтен исходному значению по модулю 2N. , где N — количество битов, формирующих значение, в unsigned int. Этот модуль равен UINT_MAX + 1.

По этой причине инициализация

unsigned int x = -1;

инициализирует x некоторым беззнаковым значением, конгруэнтным -1 по модулю UINT_MAX + 1. Между прочим, это не что иное, как UINT_MAX. Это значение имеет 1 в каждом бите формирования значения объекта unsigned int. Так работает любой беззнаковый тип.

Выражение ~0 оценивается в домене типа signed int, а затем y неявно преобразуется в unsigned int при сравнении x == y. Судя по всему, на вашей платформе преобразование дает одно и то же значение unsigned int со всеми битами, формирующими значение, установленными на 1. Отсюда равенство.

Инициализация

unsigned int x = -4;

инициализирует x некоторым беззнаковым значением, конгруэнтным -4 по модулю UINT_MAX + 1. В сравнении x == -4 правая часть преобразуется в беззнаковый тип по тем же правилам. Отсюда равенство.

person AnT    schedule 30.09.2014
comment
Точно. «Когда значение с целочисленным типом преобразуется в […] без знака, значение преобразуется путем многократного добавления или вычитания на единицу больше, чем максимальное значение, которое может быть представлено в новом типе, пока значение не окажется в диапазоне нового типа. ” (С11, §6.3.1.3). - person Stephen Canon; 30.09.2014

и как это возможно, x без знака

Это «обычные арифметические преобразования» — операнды по обе стороны от == имеют разные типы, поэтому сначала их нужно преобразовать в одинаковые типы. Правило для типов int или больше, когда типы различаются только знаком, состоит в том, что беззнаковый выигрывает, поэтому это преобразует -4 в беззнаковое эквивалентное значение, точно так же, как это было, когда вы присваивали -4 в беззнаковое целое число.

Для получения дополнительной информации см. opera">Как работают правила продвижения, если подписи по обе стороны от бинарного оператора различаются?

person Billy ONeal    schedule 30.09.2014
comment
@mafso: Ах, я имею в виду типы одного размера. Подробности по ссылке, которую я добавил. - person Billy ONeal; 01.10.2014

int отрицательные целые числа хранятся в дополнении до 2.

предположим, что у нас есть тип данных, скажем, 4 бита.

первый бит 0 представляет, что целое число положительное, в противном случае отрицательное, поэтому его максимальное значение равно 0111, т.е. 7

поэтому 1 можно записать как 0001

а для -1 оно должно быть записано в дополнении до 2, поскольку оно отрицательно;

-1 = ~(0001) +1 = (1110) + 1 = 1111;

поэтому, делая этот тип данных беззнаковым, читается -1 как 15.

person pranav prashant    schedule 05.10.2014
comment
Обратите внимание, что это верно только для машин с дополнением до 2, чего стандарт C не требует. - person Billy ONeal; 06.10.2014