Подписанные и неподписанные целые числа - PullRequest
358 голосов
/ 29 октября 2008

Правильно ли я сказать, что разница между целым числом со знаком и без знака:

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

Есть другие отличия?

Ответы [ 15 ]

314 голосов
/ 29 октября 2008

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

Да.

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

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

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

Да

89 голосов
/ 19 ноября 2008

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

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

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

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

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

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

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

56 голосов
/ 15 мая 2014

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

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

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

    • 0 до + 127
    • -1 до -128

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

15 голосов
/ 29 октября 2008

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

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

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

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

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

13 голосов
/ 27 января 2016

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

Например, глядя на 8-битное число:

без знака значения 0 до 255

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

11 голосов
/ 29 октября 2008

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

10 голосов
/ 29 апреля 2011

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

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

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

(вероятно, следует преобразовать 2 и байт, но я предполагаю, что компилятор сделает правильную вещь) Со значениями со знаком вам придется позаботиться о расширении знака и выполнить:

i = (((int) b[i]) & 0xFF) << 8 | ((int) b[i+1]) & 0xFF
4 голосов
/ 25 апреля 2013
  1. Да, целое число без знака может хранить большое значение.
  2. Нет, есть разные способы показать положительные и отрицательные значения.
  3. Да, целое число со знаком может содержать как положительные, так и отрицательные значения.
4 голосов
/ 29 октября 2008

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

4 голосов
/ 29 октября 2008

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

...