Подтвердить что ты не робот

Почему unsigned int x = -1 и int y = ~ 0 имеют одинаковое двоичное представление?

В следующем сегменте кода будет:

  • результат функции
  • значение x
  • значение y
    {
         unsigned int x=-1;
         int y;
         y = ~0;
         if(x == y)
             printf("same");
         else
             printf("not same");
     }
a. same, MAXINT, -1
b. not same, MAXINT, -MAXINT
c. same , MAXUINT, -1
d. same, MAXUINT, MAXUINT
e. not same, MAXINT, MAXUINT

Может кто-нибудь объяснить мне, как это работает или может просто объяснить фрагмент?

Я знаю это о двух дополнениях n и т.д. Каково значение MAXINT и -1? Это из-за неподписанных int и int вещей - я прав?

4b9b3361

Ответ 1

Если вы запустите эту программу, вы увидите, что ответ a неверен, а c - правильный ответ:

#include <stdio.h>
#include <limits.h>

int main() {
    unsigned int x=-1;
    int y;
    y = ~0;
    if(x == y)
        printf("same\n");
        if(x==INT_MAX) printf("INT_MAX\n");
        if(x==UINT_MAX) printf("UINT_MAX\n");
    else
        printf("not same");
    return 0;
}

Ответ 2

unsigned int x=-1;

1 является целым литералом и имеет тип int (поскольку он соответствует int). Unary -, примененный к int, не вызывает дальнейшего продвижения, поэтому -1 является int со значением -1.

При преобразовании в арифметику unsigned int modulo 2 ^ N, где N - число бит значения в unsigned int. x имеет значение 2 ^ N - 1, которое UINT_MAX (What MAX_UNIT?).

int y;
y = ~0;

Снова 0 - это тип int, в C все допустимые представления int должны иметь все биты значений int, представляющие 0, как 0. Опять же, для унарных ~ промоушн не происходит, поэтому ~0 - это int, при этом все биты значений равны 1. То, что это значение, зависит от реализации, но оно отрицательно (бит знака будет установлен), так что определенно ни один из UINT_MAX или INT_MAX. Это значение сохраняется в y без изменений.

if(x == y)
    printf("same");
else
    printf("not same");

В этом сравнении y будет преобразован в unsigned int для сравнения с x, который уже является unsigned int. Поскольку y имеет значение реализации, значение после преобразования в unsigned int все еще определено в реализации (хотя само преобразование по модулю 2 ^ N и полностью определено). Результат сравнения по-прежнему определяется реализацией.

Итак, в заключение:

определена реализация, UINT_MAX, реализация определена

Практически на одном дополнении:

не то же самое, UINT_MAX, -0 (aka 0)

знак плюс величина:

не то же самое, UINT_MAX, INT_MIN

два дополнения:

то же самое, UINT_MAX, -1

Ответ 3

Его довольно легко. Представление двойного дополнения -1 равно 0xFFFFFFFF. Следовательно, это то, что содержит x.

Оператор дополнения (~) переворачивает все биты. Таким образом, дополнение 0 представляет собой 32-битное число со всеми битами, установленными в 1 или 0xFFFFFFFF.

Изменить: как указано, он комментирует. Ответ не A. Если бы это было тогда, было бы сказано, что 0x7FFFFFFF и 0xFFFFFFFF одинаковы. Они не. Реальный ответ: C (Предполагая, что MAXUNIT - это опечатка;)).

Ответ 4

Это из-за twos-complement

Перевертывание битов приводит к битовой схеме, которая соответствует -1

Ответ 5

Так как в первом беззнаковом int вы помещаете -1, но из неподписанной int точки зрения это 0xFFFFFFFF (это то, как отрицательные целые числа хранятся в компьютере); во втором случае побитовое не вообще не смотрит на "вид" и "преобразует" 0 в 1 и наоборот, поэтому все нули 0 становятся 1 (смотря на биты), поэтому вы получаете 0xFFFFFFFF.

Следующий вопрос: почему сравнение целого числа без знака со знаком целого не отличает их? (численно 4294967295, конечно, не равно -1, хотя их представление в компьютере такое же). В самом деле, это возможно, но ясно, что C не предусматривает такого различия, и это "естественно", поскольку процессор не может сделать это самостоятельно (я не уверен, что это последнее предложение всегда true,... но это для большинства процессоров): чтобы принять во внимание это различие в asm, вам нужно добавить дополнительный код.

С точки зрения C вам нужно решить, следует ли вводить int в unsigned int или подписали int в unsigned int. Но отрицательное число не может быть записано в непознанный, и, с другой стороны, беззнаковое число может вызвать переполнение (например, для 4294967295 вам нужен 64-битный регистр (или 33-битный реестр!), Чтобы иметь возможность иметь он и еще сможет вычислить его отрицательное значение)...

Так что, скорее всего, самое естественное - избегать странного литья и разрешить сравнение "cpu like", которое в этом случае приводит к 0xFFFFFFFF (-1 на 32 бит) по сравнению с 0xFFFFFFFF (~ 0 на 32 бит), которые то же самое и больше в генетическом можно рассматривать как MAXUINT (максимальное целое без знака, которое может быть удержано), а другое как -1. (Посмотрите на свой аппарат limits.h включить, чтобы проверить его)