Почему 0x1 интерпретируется как менее 0xC0000000? - PullRequest
2 голосов
/ 12 февраля 2020

Я изучаю двоичное представление целых чисел и попытался написать функцию, которая возвращает int, умноженное на 2, используя насыщенность. Мысленный процесс заключается в том, что если значение положительно переполняется, функция возвращает INT_MAX, и наоборот, если оно отрицательно переполняется, возвращается INT_MIN. Во всех других случаях двоичное значение смещается влево на 1.

. Мне интересно, почему мне нужно привести значение 0xC0000000 как int, чтобы моя функция работала правильно, когда Я передаю аргумент x = 1.

Вот моя функция:

int timestwo (int x){
    if(x >= 0x40000000) // INT_MAX/2 + 1
        return 0x7fffffff; // INT_MAX
    else if(x < (int) 0xC0000000) // INT_MIN/2
        return 0x80000000; // INT_MIN
    else
        return x << 1;
    return 0;
}

Ответы [ 2 ]

5 голосов
/ 12 февраля 2020

Шестнадцатеричные (и восьмеричные) литералы в C набираются с использованием наименьшего повышенного типа (= int или более высокий тип ранжирования), со знаком или без знака, который может вместить значение. Это отличается от десятичных литералов, которые остаются в знаковых типах, если у них нет суффикса u / U, или в других типах без знака ( 6.4.4.1p5 ):

integer-literal types

Это делает 0xC0000000 в системе с 32-разрядными целыми числами без знака и сравнивает (или иным образом соединяет с помощью оператора) без знака с тем же знаком ранг заставляет подписанного стать неподписанным ( 6.3.1.8 ), поэтому без (int) вы получаете неявный (unsigned int)x < (unsigned int) 0xC0000000.

2 голосов
/ 12 февраля 2020

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

Результат приведения к int фактически определяется реализацией, хотя в системе дополнения до двух это обычно приводит к тому, что вы ожидаете.

...