Правильно ли я сказать, что разница между целым числом со знаком и без знака такова:
- Без знака может иметь большее положительное значение, а не отрицательное значение.
- Неподписанный использует начальный бит как часть значения, в то время как подписанная версия использует самый левый бит, чтобы определить, является ли число положительным или отрицательным.
- целые числа со знаком могут содержать как положительные, так и отрицательные числа.
Есть другие отличия?
language-agnostic
integer
unsigned
signed
Шимми Вайцхандлер
источник
источник
Ответы:
Да.
Существуют разные способы представления целых чисел со знаком. Самым простым для визуализации является использование самого левого бита в качестве флага ( знак и величина ), но более распространенным является дополнение к двум . Оба используются в большинстве современных микропроцессоров - с плавающей запятой используются знак и величина, а целочисленная арифметика использует два дополнения.
да
источник
Я пойду в различия на аппаратном уровне, на x86. Это в основном не имеет значения, если вы не пишете компилятор или не используете язык ассемблера. Но это приятно знать.
Во-первых, в x86 есть встроенная поддержка представления чисел со знаком в дополнение к двум . Вы можете использовать другие представления, но это потребует больше инструкций и, как правило, будет пустой тратой процессорного времени.
Что я имею в виду под «нативной поддержкой»? По сути, я имею в виду, что есть набор инструкций, которые вы используете для чисел без знака, и другой набор, который вы используете для чисел со знаком. Беззнаковые числа могут находиться в тех же регистрах, что и подписанные числа, и действительно, вы можете смешивать подписанные и неподписанные инструкции, не беспокоя процессор. Компилятор (или программист на ассемблере) должен следить за тем, подписано ли число или нет, и использовать соответствующие инструкции.
Во-первых, у двух чисел дополнения есть свойство, что сложение и вычитание такие же, как для чисел без знака. Не имеет значения, являются ли числа положительными или отрицательными. (Таким образом, вы просто идете вперед
ADD
иSUB
ваши номера без беспокойства.)Различия начинают проявляться, когда дело доходит до сравнений. В x86 есть простой способ их различения: выше / ниже указывает сравнение без знака и больше / меньше, чем сравнение со знаком. (Например,
JAE
означает «Перейти, если выше или равно» и без знака.)Есть также два набора команд умножения и деления для работы со знаковыми и беззнаковыми целыми числами.
И наконец: если вы хотите проверить, скажем, переполнение, вы бы сделали это по-разному для чисел со знаком и для чисел без знака.
источник
Он только спросил о подписанных и неподписанных. Не знаю, почему люди добавляют дополнительные вещи в это. Позвольте мне сказать вам ответ.
Без знака: состоит только из неотрицательных значений, то есть от 0 до 255.
Подпись: состоит из отрицательных и положительных значений, но в разных форматах, таких как
И это объяснение о 8-битной системе счисления.
источник
Всего несколько баллов за полноту:
этот ответ обсуждает только целочисленные представления. Там могут быть другие ответы для плавающей запятой;
представление отрицательного числа может варьироваться. Наиболее распространенным (на сегодняшний день - почти универсальным сегодня) в использовании сегодня является дополнение двух . Другие представления включают в себя дополнение (довольно редкое) и величину со знаком (исчезающе редко - возможно, только для музейных экспонатов), которая просто использует старший бит в качестве индикатора знака, а оставшиеся биты представляют абсолютное значение числа.
При использовании дополнения до двух переменная может представлять больший диапазон (на единицу) отрицательных чисел, чем положительных чисел. Это связано с тем, что в «положительные» числа входит ноль (поскольку бит знака не установлен для нуля), а не отрицательные числа. Это означает, что абсолютное значение наименьшего отрицательного числа не может быть представлено.
при использовании дополнения или величины со знаком вы можете иметь ноль, представленный как положительное или отрицательное число (что является одной из нескольких причин, по которым эти представления обычно не используются).
источник
Согласно тому, что мы узнали в классе, целые числа со знаком могут представлять как положительные, так и отрицательные числа, в то время как целые числа без знака являются только неотрицательными.
Например, глядя на 8-битное число:
значения без знака
0
для255
Подписанные значения от
-128
до127
источник
Все, кроме пункта 2, верно. Существует много различных обозначений для подписанных целых, некоторые реализации используют первую, другие используют последнюю, а третьи используют что-то совершенно другое. Все зависит от платформы, с которой вы работаете.
источник
Другое отличие заключается в том, что вы конвертируете между целыми числами разных размеров.
Например, если вы извлекаете целое число из потока байтов (скажем, 16 битов для простоты) со значениями без знака, вы можете сделать:
(вероятно, должен привести 2- й байт, но я предполагаю, что компилятор сделает правильную вещь)
Со значениями со знаком вам придется беспокоиться о расширении знака и делать:
источник
Вообще говоря, это правильно. Не зная больше о том, почему вы ищете различия, я не могу представить себе никаких других различий между подписанным и неподписанным.
источник
Помимо того, что говорили другие, в C вы не можете переполнить целое число без знака; поведение определено как модульная арифметика. Вы можете переполнить целое число со знаком и, теоретически (хотя на практике это не актуально для современных основных систем), переполнение может вызвать ошибку (возможно, аналогичную ошибке деления на ноль).
источник
источник
(в ответ на второй вопрос) Используя только знаковый бит (а не 2-е дополнение), вы можете получить -0. Не очень красиво.
источник
Целые числа со знаком в 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 провел различия так же, как и он, но они такие, какие есть.
источник
Целые числа без знака гораздо чаще попадают в конкретную ловушку, чем целые числа со знаком. Эта ловушка связана с тем фактом, что, хотя приведенные выше пункты 1 и 3 являются правильными, обоим типам целых чисел может быть присвоено значение за пределами того, что он может «удерживать», и он будет преобразован без вывода сообщений.
Когда вы запустите это, вы получите следующий вывод, даже если оба значения были присвоены -1 и были объявлены по-разному.
источник
Единственное гарантированное различие между значением со знаком и без знака в C состоит в том, что значение со знаком может быть отрицательным, 0 или положительным, тогда как значение без знака может быть только 0 или положительным. Проблема в том, что C не определяет формат типов (поэтому вы не знаете, что ваши целые числа в дополнении до двух). Строго говоря, первые два пункта, которые вы упомянули, неверны.
источник
Вы должны использовать целые числа без знака при программировании на встроенных системах. В циклах, когда нет необходимости в целых числах со знаком, использование целых чисел без знака спасет безопасность, необходимую для проектирования таких систем.
источник