Знаковый ноль — это ноль с соответствующим знаком . В обычной арифметике число 0 не имеет знака, поэтому −0, +0 и 0 эквивалентны. Однако в вычислениях некоторые представления чисел допускают существование двух нулей, часто обозначаемых как −0 ( отрицательный ноль ) и +0 ( положительный ноль ), которые считаются равными с помощью числовых операций сравнения, но с возможным различным поведением в конкретных операциях. Это происходит в знаковых представлениях чисел со знаком величины и дополнением до единицы для целых чисел, а также в большинстве представлений чисел с плавающей точкой . Число 0 обычно кодируется как +0, но все равно может быть представлено как +0, −0 или 0.
Стандарт IEEE 754 для арифметики с плавающей точкой (в настоящее время используемый большинством компьютеров и языков программирования, поддерживающих числа с плавающей точкой) требует как +0, так и −0. Действительную арифметику со знаковыми нулями можно считать вариантом расширенной действительной числовой прямой, такой что 1/−0 = −∞ и 1/+0 = +∞; деление не определено только для ±0/±0 и ±∞/±∞.
Отрицательно знаковый ноль перекликается с концепцией математического анализа приближения к 0 снизу как одностороннего предела , который может быть обозначен как x → 0 − , x → 0− или x → ↑0. Обозначение «−0» может использоваться неформально для обозначения отрицательного числа, округленного до нуля. Концепция отрицательного нуля также имеет некоторые теоретические приложения в статистической механике и других дисциплинах.
Утверждается, что включение знакового нуля в IEEE 754 значительно облегчает достижение числовой точности в некоторых критических задачах, [1] в частности, при вычислениях со сложными элементарными функциями. [2] С другой стороны, концепция знакового нуля противоречит обычному предположению, сделанному в математике, что отрицательный ноль имеет то же значение, что и ноль. Представления, которые допускают отрицательный ноль, могут быть источником ошибок в программах, если разработчики программного обеспечения не учитывают, что хотя два нулевых представления ведут себя как равные при числовых сравнениях, они дают разные результаты в некоторых операциях.
Двоичные целочисленные форматы могут использовать различные кодировки . В широко используемой кодировке с дополнением до двух ноль является беззнаковым. В 1+7-битном знаково-величинном представлении для целых чисел отрицательный ноль представлен битовой строкой . В 8-битном представлении с дополнением до единиц отрицательный ноль представлен битовой строкой . Во всех этих трех кодировках положительный или беззнаковый ноль представлен . Однако последние две кодировки (со знаковым нулем) нечасто встречаются для целочисленных форматов. Наиболее распространенными форматами со знаковым нулем являются форматы с плавающей точкой ( форматы IEEE 754 или аналогичные), описанные ниже.10000000
11111111
00000000
В двоичных форматах с плавающей точкой IEEE 754 нулевые значения представлены смещенной экспонентой и мантиссом , которые оба равны нулю. Отрицательный ноль имеет бит знака, установленный в единицу. Отрицательный ноль может быть получен в результате определенных вычислений, например, в результате арифметического переполнения отрицательного числа (возможны и другие результаты), или −1.0×0.0
, или просто как −0.0
.
В десятичных форматах с плавающей точкой IEEE 754 отрицательный ноль представлен показателем степени, который может быть любым допустимым показателем в диапазоне для данного формата, при этом истинная значимая часть равна нулю, а знаковый бит равен единице.
Стандарт IEEE 754 с плавающей точкой определяет поведение положительного нуля и отрицательного нуля при различных операциях. Результат может зависеть от текущих настроек режима округления IEEE .
В системах, включающих как знаковые, так и беззнаковые нули, для знаковых нулей иногда используется обозначение и .
Сложение и умножение коммутативны, но есть некоторые специальные правила, которые необходимо соблюдать, что означает, что обычные математические правила для алгебраического упрощения могут не применяться. Знак ниже показывает полученные результаты с плавающей точкой (это не обычный оператор равенства).
При умножении и делении всегда соблюдается обычное правило знаков:
Существуют специальные правила прибавления или вычитания знакового нуля:
Из-за отрицательного нуля (а также когда режим округления вверх или вниз) выражения −( x − y ) и (− x ) − (− y ) для переменных с плавающей точкой x и y не могут быть заменены на y − x . Однако (−0) + x можно заменить на x с округлением до ближайшего (за исключением случаев, когда x может быть сигнальным NaN ).
Некоторые другие особые правила:
Деление ненулевого числа на ноль устанавливает флаг деления на ноль , а операция, производящая NaN, устанавливает флаг недопустимой операции. Обработчик исключений вызывается, если он включен для соответствующего флага.
Согласно стандарту IEEE 754, отрицательный ноль и положительный ноль должны сравниваться как равные с обычными (числовыми) операторами сравнения, такими как ==
операторы C и Java . В этих языках могут потребоваться специальные программные приемы, чтобы различать два значения:
copysign()
(операция IEEE 754 copySign) для копирования знака нуля в некоторое ненулевое число;signbit()
(операция IEEE 754 isSignMinus), который возвращает информацию о том, установлен ли знаковый бит числа;Примечание: Приведение к целочисленному типу не всегда будет работать, особенно в системах с дополнительным кодом.
Однако некоторые языки программирования могут предоставлять альтернативные операторы сравнения, которые различают два нуля. Это касается, например, метода equals в Double
классе-оболочке Java . [4]
Неформально можно использовать обозначение "−0" для отрицательного значения, округленного до нуля. Это обозначение может быть полезным, когда отрицательный знак имеет значение; например, при табулировании температур по Цельсию , где отрицательный знак означает ниже нуля .
В статистической механике иногда используют отрицательные температуры для описания систем с инверсией населенности , которые можно считать имеющими температуру больше положительной бесконечности, поскольку коэффициент энергии в функции распределения населенности равен −1/Температура. В этом контексте температура −0 является (теоретической) температурой, большей любой другой отрицательной температуры, соответствующей (теоретической) максимально возможной степени инверсии населенности, противоположной +0. [5]
SIGN
в Fortran 95 для учета отрицательного нуля