Я знаю, что целочисленные значения 0
и -0
по сути совпадают. Но мне интересно, можно ли их различить.
Например, как узнать, назначена ли переменная -0
?
bool IsNegative(int num)
{
// How ?
}
int num = -0;
int additinon = 5;
num += (IsNegative(num)) ? -addition : addition;
Сохраняется ли значение -0
в памяти точно так же, как 0
?
c++
int
zero
negative-number
Филип Минкс
источник
источник
int
представлены в виде двух дополнений (наиболее часто встречающихся)0
и-0
имеют идентичные побитовые представления.int
. См. Дополнительное кодирование Единиц .Ответы:
Это зависит от машины, на которую вы нацеливаетесь.
На машине, которая использует представление дополнения до 2 для целых чисел, нет разницы на битовом уровне между
0
и-0
(они имеют одинаковое представление)Если бы в вашей машине использовалось дополнительное оборудование , вы бы определенно могли
Очевидно, мы говорим об использовании встроенной поддержки , процессоры серии x86 имеют встроенную поддержку для представления чисел со знаком в виде дополнения до двух. Использование других представлений определенно возможно, но, вероятно, будет менее эффективным и потребует большего количества инструкций.
(Как также отметил JerryCoffin: даже если дополнение рассматривается в основном по историческим причинам, представления величины со знаком все еще довольно распространены и имеют отдельное представление для отрицательного и положительного нуля)
источник
0
и-0
являются разные ? Честно говоря, я ожидал, что он будет вести себя больше как разрешение двухбитовых представлений одного и того же значения, и ваша программа может использовать любое из них, которое ей нравится.-0
, то есть результат применения унарного-
оператора к целочисленной константе0
, является отрицательным нулевым представлением. Независимо от представления, в стандарте никогда не говорится0
и-0
математически разные значения, только то, что может быть битовый шаблон отрицательного нуля. Если есть, то оно по-прежнему представляет собой то же числовое значение, 0.Для
int
(в почти универсальном представлении с «дополнением до 2») представления0
и-0
совпадают. (Они могут отличаться для других представлений чисел, например, для чисел с плавающей запятой IEEE 754.)источник
Начнем с представления 0 в дополнении до 2 (конечно, существует много других систем и представлений, здесь я имею в виду именно эту), предполагая, что 8-битный ноль равен:
Теперь давайте перевернем все биты и добавим 1, чтобы получить двойное дополнение:
мы получили
0000 0000
, и это тоже представление -0.Но обратите внимание, что в дополнении до 1 знаковый 0 - это 0000 0000, а -0 - 1111 1111.
источник
Я решил оставить этот ответ, поскольку реализации C и C ++ обычно тесно связаны, но на самом деле он не соответствует стандарту C, как я думал. Дело в том, что стандарт C ++ не определяет, что происходит в подобных случаях. Также важно, что представления без двойного дополнения чрезвычайно редки в реальном мире, и что даже там, где они действительно существуют, они часто скрывают разницу во многих случаях, а не выставляют ее как нечто, что кто-то может легко ожидать обнаружить.
Поведение отрицательных нулей в целочисленных представлениях, в которых они существуют, не так строго определено в стандарте C ++, как в стандарте C. Однако он ссылается на стандарт C (ISO / IEC 9899: 1999) в качестве нормативной ссылки на верхнем уровне [1.2].
В стандарте C [6.2.6.2] отрицательный ноль может быть только результатом побитовых операций или операций, в которых отрицательный ноль уже присутствует (например, умножение или деление отрицательного нуля на значение или добавление отрицательного нуля к ноль) - применение унарного оператора минус к значению нормального нуля, как в вашем примере, поэтому гарантированно приведет к нормальному нулю.
Даже в случаях, когда может генерироваться отрицательный ноль, нет никакой гарантии, что они будут, даже в системе, которая поддерживает отрицательный ноль:
Таким образом, можно сделать вывод: нет, надежного способа выявить этот случай нет. Даже если бы не тот факт, что представления без двоичного дополнения очень редко встречаются в современных компьютерных системах.
В стандарте C ++, в свою очередь, не упоминается термин «отрицательный ноль» и очень мало обсуждаются детали представлений величины со знаком и одного дополнения, за исключением [3.9.1, параграф 7], что они разрешены.
источник
_Bool
или_Complex
или назначенных инициализаторов, или составных литералов). Стандарт C ++ знает, как включить стандарт C, когда он этого хочет - например, [basic.fundamental] / p3: «Целочисленные типы со знаком и без знака должны удовлетворять ограничениям, приведенным в стандарте C, раздел 5.2.4.2.1».Если ваша машина имеет различные представления для
-0
и+0
, тогдаmemcmp
вы сможете их различать.Если биты заполнения присутствуют, на самом деле может быть несколько представлений для значений, отличных от нуля.
источник
В спецификации языка C ++ нет такого int, как отрицательный ноль .
Единственное значение, которое имеют эти два слова, - это унарный оператор,
-
применяемый к нему0
, так же как три плюс пять - это просто бинарный оператор,+
применяемый к3
и5
.Если бы существовал отчетливый отрицательный ноль , дополнение до двух (наиболее распространенное представление целочисленных типов) было бы недостаточным представлением для реализаций C ++, поскольку невозможно представить две формы нуля.
Напротив, числа с плавающей запятой (согласно IEEE) имеют отдельные положительные и отрицательные нули. Их можно различить, например, разделив на них 1. Положительный ноль дает положительную бесконечность; отрицательный ноль дает отрицательную бесконечность.
Однако, если случаются разные представления в памяти int 0 (или любого int, или любого другого значения любого другого типа), вы можете использовать,
memcmp
чтобы обнаружить это:Конечно, если бы это произошло, вне прямых операций с памятью, два значения по-прежнему работали бы точно так же.
источник
Чтобы упростить, мне было легче визуализировать.
Тип int (_32) хранится с 32 битами . 32 бита означает 2 ^ 32 = 4294967296 уникальных значений . Таким образом:
диапазон данных unsigned int от 0 до 4294967295
В случае отрицательных значений это зависит от того, как они хранятся. В случае
В случае с дополнением до единицы существует значение -0.
источник
int
не хранятся 32 бита, в настоящее время более популярны, чем платформы с одним дополнением.