Знаковый ноль — это ноль с соответствующим знаком . В обычной арифметике число 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-битном знаково-величинном представлении для целых чисел отрицательный ноль представлен битовой строкой 1000 0000. В 8-битном представлении с дополнением до единиц отрицательный ноль представлен битовой строкой 1111 1111. Во всех этих трех кодировках положительный или беззнаковый ноль представлен как 0000 0000. Однако последние две кодировки (со знаковым нулем) нетипичны для целочисленных форматов. Наиболее распространенными форматами со знаковым нулем являются форматы с плавающей точкой ( форматы IEEE 754 или аналогичные), описанные ниже.
В двоичных форматах с плавающей точкой 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 для учета отрицательного нуля