Подписанные и неподписанные целые числа

Я правильно говорю, что разница между целым числом, подписанным и без знака, равна:

  • Unsigned может содержать большее положительное значение и отрицательное значение.
  • Unsigned использует ведущий бит как часть значения, в то время как подписанная версия использует самый левый бит, чтобы определить, является ли число положительным или отрицательным.
  • знаковые целые числа могут содержать как положительные, так и отрицательные числа.

Любые другие отличия?

Ответ 1

Без знака может иметь большее положительное значение, а не отрицательное значение.

Да.

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

Существуют разные способы представления целых чисел со знаком. Самым простым для визуализации является использование самого левого бита в качестве флага (знак и величина), но более распространенным является два дополнения. Оба используются в большинстве современных микропроцессоров - с плавающей запятой используются знак и величина, а целочисленная арифметика использует два дополнения.

целые числа со знаком могут содержать как положительные, так и отрицательные числа.

да

Ответ 2

Я пойду на различия на аппаратном уровне, на x86. Это в основном не имеет значения, если вы не пишете компилятор или не используете язык ассемблера. Но это приятно знать.

Во-первых, x86 имеет встроенную поддержку двух дополнений для представления подписанных чисел. Вы можете использовать другие представления, но для этого потребуется больше инструкций и, как правило, будет пустой тратой времени процессора.

Что я подразумеваю под "родной поддержкой"? В основном я имею в виду, что есть набор инструкций, которые вы используете для чисел без знака и другого набора, который вы используете для подписанных чисел. Беззнаковые числа могут находиться в тех же регистрах, что и подписанные числа, и вы можете смешивать подписанные и неподписанные инструкции, не беспокоясь о процессоре. Это до компилятора (или программиста сборки), чтобы отслеживать, подписано ли число или нет, и используйте соответствующие инструкции.

Во-первых, два номера дополнений обладают тем свойством, что сложение и вычитание являются такими же, как для неподписанных чисел. Не имеет значения, являются ли цифры положительными или отрицательными. (Таким образом, вы просто продолжаете и ADD и SUB свои номера, не беспокоясь.)

Различия начинают показывать, когда дело доходит до сравнений. x86 имеет простой способ их дифференцирования: выше/ниже указывает сравнение без знака и больше/меньше, чем указывает сопоставленное сравнение. (Например, JAE означает "Перейти, если выше или равно" и не имеет знака.)

Существует также два набора инструкций умножения и деления для работы с подписанными и беззнаковыми целыми числами.

Наконец: если вы хотите проверить, скажем, переполнение, вы сделали бы это по-другому для подписанных и для чисел без знака.

Ответ 3

Он только спросил о подписанных и неподписанных. Не знаю, почему люди добавляют дополнительные вещи в это. Позвольте мне сказать вам ответ.

  1. Без знака: он состоит только из неотрицательных значений, то есть от 0 до 255.

  2. Подпись: состоит из отрицательных и положительных значений, но в разных форматах, таких как

    • От 0 до +127
    • -1 - -1 28

И это объяснение о 8-битной системе счисления.

Ответ 4

Всего лишь несколько баллов за полноту:

  • В этом ответе обсуждаются только целые представления. Могут быть другие ответы для плавающей запятой;

  • представление отрицательного числа может меняться. Наиболее распространенным сегодня (сегодня - сегодня почти универсальным) сегодня является два дополнения. Другие представления включают одно дополнение (довольно редко) и подписанная величина (исчезающе редко встречающаяся, вероятно, только на музейных произведениях), которая просто использует высокий бит в качестве индикатора с остаются биты, представляющие абсолютное значение числа.

  • При использовании двух дополнений переменная может представлять больший диапазон (на единицу) отрицательных чисел, чем положительные числа. Это связано с тем, что нуль включен в "положительные" числа (поскольку знаковый бит не установлен для нуля), но не отрицательные числа. Это означает, что абсолютное значение наименьшего отрицательного числа не может быть представлено.

  • при использовании одного дополнения или знаковой величины вы можете иметь нуль, представленный как положительное или отрицательное число (что является одной из нескольких причин, по которым эти представления обычно не используются).

Ответ 5

В соответствии с тем, что мы узнали в классе, целые числа со знаком могут представлять как положительные, так и отрицательные числа, а целые числа без знака - только неотрицательные.

Например, глядя на 8-разрядный номер:

неподписанные значения 0 - 255

значенные значения варьируются от -128 до 127

Ответ 6

Все, кроме пункта 2, является правильным. Существует много разных обозначений для подписанных ints, некоторые реализации используют первый, другие используют последний, а другие используют нечто совершенно другое. Все зависит от платформы, с которой вы работаете.

Ответ 7

Другое отличие заключается в том, что вы конвертируете целые числа разных размеров.

Например, если вы извлекаете целое число из байтового потока (например, 16 бит для простоты), с неподписанными значениями вы можете сделать:

i = ((int) b[j]) << 8 | b[j+1]

(должен, вероятно, записать 2 nd байт, но я предполагаю, что компилятор пойдет правильно)

С подписанными значениями вам придется беспокоиться о расширении знака и делать:

i = (((int) b[i]) & 0xFF) << 8 | ((int) b[i+1]) & 0xFF

Ответ 8

Вообще говоря, это правильно. Не зная ничего больше о том, почему вы ищете различия, я не могу думать о каких-либо других отличиях между подписанными и неподписанными.

Ответ 9

(в ответ на второй вопрос). Используя только битовый знак (а не 2 дополнение), вы можете получить -0. Не очень красиво.

Ответ 10

Помимо того, что другие сказали в C, вы не можете переполнять целое число без знака; поведение определяется как арифметика модуля. Вы можете переполнить целое число со знаком и, теоретически (хотя и не на практике в текущих системах основного), переполнение может вызвать ошибку (возможно, похоже на деление на нулевую ошибку).

Ответ 11

  • Да, целое число без знака может хранить большое значение.
  • Нет, есть разные способы показать положительные и отрицательные значения.
  • Да, целое число со знаком может содержать как положительные, так и отрицательные значения.

Ответ 12

Целые числа без знака гораздо чаще поймают вас в определенной ловушке, чем целые числа со знаком. Ловушка исходит из того, что в то время как 1 и 3 выше правильные, обеим типам целых чисел может быть присвоено значение за пределами того, что он может "удерживать", и он будет преобразован молча.

unsigned int ui = -1;
signed int si = -1;

if (ui < 0) {
    printf("unsigned < 0\n");
}
if (si < 0) {
    printf("signed < 0\n");
}
if (ui == si) {
    printf("%d == %d\n", ui, si);
    printf("%ud == %ud\n", ui, si);
}

Когда вы запустите это, вы получите следующий вывод, даже если оба значения были присвоены -1 и объявлены по-разному.

signed < 0
-1 == -1
4294967295d == 4294967295d

Ответ 13

Подписанные целые числа в C представляют числа. Если a и b являются переменными со знаком целочисленных типов, стандарт никогда не потребует, чтобы компилятор сделал выражение a+=b хранилищем в a чем-либо другим, кроме арифметической суммы их соответствующих значений. Разумеется, если бы арифметическая сумма не уместилась в a, процессор, возможно, не смог бы ее поместить, но стандарт не потребовал бы, чтобы компилятор обрезал или обернул значение или сделал что-нибудь еще в этом случае, если значения, превышающие пределы для их типов. Обратите внимание, что, хотя стандарт не требует этого, реализациям C допускается ловушка арифметических переполнений со значными значениями.

Неподписанные целые числа в C ведут себя как абстрактные алгебраические кольца целых чисел, которые конгруэнтны по модулю некоторой степени из двух, за исключением сценариев, связанных с преобразованиями или операциями с более крупными типами. Преобразование целого числа любого размера в 32-разрядный неподписанный тип даст член, соответствующий вещам, которые соответствуют этому целому модулю 4 294 967 296. Причина, вычитающая 3 из 2, дает 4 294 967 295, состоит в том, что добавление чего-то конгруэнтного к 3 к чему-то, сравнимому с 4 294 967 295, даст что-то совпадающее с 2.

Абстрактные типы алгебраических колец часто бывают полезными; к сожалению, C использует подпись как решающий фактор для того, должен ли тип вести себя как кольцо. Хуже того, значения без знака рассматриваются как числа, а не члены кольца при преобразовании в более крупные типы, а значения без знака меньше int преобразуются в числа, когда на них выполняется любая арифметика. Если v есть uint32_t, что равно 4,294,967,294, то v*=v; должен сделать v=4. К сожалению, если int - 64 бита, то неизвестно, что может сделать v*=v;.

Учитывая стандартный стандарт, я предлагаю использовать неподписанные типы в ситуациях, когда требуется поведение, связанное с алгебраическими кольцами, и подписанные типы, когда нужно представлять числа. К сожалению, C рисовал различия так, как сделал, но они такие, какие они есть.

Ответ 14

Единственное гарантированное различие между подписанным и неподписанным значением в C состоит в том, что подписанное значение может быть отрицательным, 0 или положительным, а unsigned может быть только 0 или положительным. Проблема в том, что C не определяет формат типов (поэтому вы не знаете, что ваши целые числа находятся в двух дополнениях). Строго говоря, первые два упомянутых вами момента неверны.

Ответ 15

При программировании на встроенных системах вы должны использовать неподписанные целые числа. В циклах, когда нет необходимости в целых числах со знаком, использование целых чисел без знака спасет безопасность, необходимую для проектирования таких систем.