Целочисленное переполнение/незаполнение

Я изучаю целочисленные переполнения и потери значимости, и мне было интересно, можно ли контролировать значение j, вводя отрицательный ввод n?

int i = n;
size_t j = i;
printf("%lu",j);

например, если я хочу, чтобы значение «j» было равно 255, можно ли создать отрицательное число «n», чтобы получить этот результат?


person NEz    schedule 20.09.2017    source источник
comment
Да это так! Вы можете установить n на 255. :-P   -  person Charles Srstka    schedule 20.09.2017
comment
Не существует такой вещи, как потеря значимости целых чисел. В общепринятой номенклатуре потеря значимости может происходить только в арифметике с плавающей запятой. На ваш вопрос ответ прост: просто установите n на 255. Простота и банальность ответа наводит на мысль, что вы что-то упустили в своем вопросе.   -  person AnT    schedule 20.09.2017
comment
извините, я имел в виду, давая отрицательное значение. я обновил вопрос   -  person NEz    schedule 20.09.2017
comment
Какой тип n? В любом случае, невозможно ответить на вопрос об отрицательном значении n, не зная точных характеристик типа size_t (в частности, его диапазона). Это зависит от платформы. И вы должны использовать %zu для печати size_t значений, а не %lu.   -  person AnT    schedule 20.09.2017
comment
n имеет тип int, а size_t обычно имеет длину без знака, я думаю.   -  person NEz    schedule 20.09.2017
comment
Во-первых, обычно недостаточно хорошо. Во-вторых, это совсем не помогает, поскольку диапазон unsigned long по-прежнему зависит от реализации, что делает невозможным ответ на ваш вопрос без изучения всех возможных комбинаций.   -  person AnT    schedule 20.09.2017
comment
Если вы приведете переменную, содержащую -1, к uint8_t, вы получите 255. Однако 255 меньше, чем 0x8000, поэтому я не думаю, что вы сможете получить его, приведя отрицательное значение к любому целочисленному типу, превышающему 8 бит. И само собой разумеется, я не думаю, что вы найдете какие-либо современные платформы (или древние, если на то пошло), на которых unsigned long имеет размер всего 8 бит.   -  person Charles Srstka    schedule 20.09.2017
comment
@Charles Srstka: На странной воображаемой платформе с 64-битной int и 32-битной size_t это было бы вполне возможно. Установка i в -9223372036854775553 приведет к 255 в j. Но правда, если int не шире, чем size_t, то отрицательное значение в i никогда не даст 255 в j.   -  person AnT    schedule 20.09.2017
comment
@AnT Ах, ты прав. Однако я был бы весьма шокирован, увидев любую платформу, на которой int было бы больше, чем size_t.   -  person Charles Srstka    schedule 20.09.2017
comment
@CharlesSrstka unsigned long должно быть не менее 32 бит.   -  person M.M    schedule 20.09.2017
comment
@M.M. Ты не говори!   -  person Charles Srstka    schedule 20.09.2017
comment
Что такое underflow? Пожалуйста, удалите все underflow слова из заголовка и вопроса.   -  person Abhineet    schedule 20.09.2017


Ответы (1)


Я думаю, что вы ищете

signed char i = -1;
unsigned char j = i;
printf("%u\n", j);

В 8 битах число со знаком -1 "переносится" на беззнаковое значение 255.

Вы спросили о size_t, потому что да, это беззнаковый тип, но обычно он 32 или даже 64 бита. При таких размерах число 255 представимо (и имеет одинаковое представление) как в знаковом, так и в беззнаковом вариантах, поэтому отрицательного числа, соответствующего 255, не существует. Но вы, безусловно, можете увидеть аналогичные эффекты, используя разные значения. Например, на машине с 32-битными целыми числами этот код:

unsigned int i = 4294967041;
int j = i;
printf("%d\n", j);

скорее всего напечатает -255. Это значение получается потому, что 2^32 - 255 = 4294967041.

person Steve Summit    schedule 20.09.2017
comment
В последнем коде поведение определяется реализацией (и может вызывать сигнал) - person M.M; 20.09.2017