Fact-checked by Grok 2 weeks ago

Signed zero

In , signed zero refers to the distinct representations of positive zero (+0) and negative zero (−0) in the standard, where the value zero is encoded with a (0 for positive, 1 for negative) while the exponent and fraction fields are set to zero. This feature arises during underflow, when a nonzero value becomes too small to represent and rounds to zero, preserving the original sign to maintain mathematical consistency in subsequent operations. For example, in single-precision format, +0 is represented as the hexadecimal value 00000000, and −0 as 80000000. The inclusion of signed zero enables precise handling of edge cases in arithmetic, such as , where $1 / +0 = +\infty and $1 / -0 = -\infty, reflecting the direction from which the zero was approached. In comparisons, signed zeros are treated as equal in most checks but distinguishable in ordered comparisons, with −0 < +0 evaluating to true. This design supports gradual underflow and extends the representable range near zero, including signed subnormal numbers, while ensuring exact results in addition, subtraction, and remainder operations involving zeros. Although +0 and −0 are mathematically equivalent in value, their sign influences function behaviors, such as limits in trigonometric or logarithmic computations, to avoid loss of directional information. Signed zero is a core element of binary floating-point formats like binary32 (single precision) and binary64 (double precision), and it applies similarly to infinities and NaNs, which also carry a sign bit despite not requiring it for magnitude. Its implementation in hardware and software, such as in SPARC and x86 architectures, underscores the standard's emphasis on reproducibility and robustness in numerical computing.

Representations

In IEEE 754 floating-point

In the IEEE 754 standard for binary floating-point arithmetic, signed zero is encoded using a dedicated sign bit, with the exponent and significand (mantissa) fields set entirely to zero. The sign bit, which is the most significant bit, distinguishes between positive zero (+0, sign bit 0) and negative zero (−0, sign bit 1). This representation applies across the standard's binary formats, including single precision (binary32, 32 bits total: 1 sign, 8 exponent, 23 significand), double precision (binary64, 64 bits: 1 sign, 11 exponent, 52 significand), and quadruple precision (binary128, 128 bits: 1 sign, 15 exponent, 112 significand). The specific bit patterns for signed zero in these formats are as follows, where the sign bit alone varies:
FormatTotal Bits+0 (Hexadecimal)−0 (Hexadecimal)
Single (binary32)320x000000000x80000000
Double (binary64)640x00000000000000000x8000000000000000
Quadruple (binary128)1280x000000000000000000000000000000000x80000000000000000000000000000000
These patterns ensure that zero is distinctly represented without implying a non-zero magnitude. The IEEE 754-1985 standard, officially adopted on August 12, 1985, by the , first formalized these signed zero representations to address inconsistencies in pre-standard floating-point implementations and to support reliable numerical computations. This inclusion preserved the sign information from operands approaching zero, enabling better handling of limits in mathematical functions and maintaining continuity in behaviors like limits from positive and negative directions. The 2008 revision of the standard extended support to quadruple precision while retaining the same encoding principles for signed zero. Signed zeros are distinguished from other special values in IEEE 754: infinities use an all-ones exponent with an all-zero significand (sign bit varying for ±∞), while not-a-numbers (NaNs) use an all-ones exponent with a non-zero significand. This separation ensures zeros do not overlap with these representations, allowing hardware and software to detect and handle them appropriately.

In other numeric formats

In the decimal floating-point formats defined by IEEE 754, such as decimal32 and decimal64, signed zero is represented using a dedicated sign bit (0 for positive zero and 1 for negative zero), combined with a zero cohort (exponent field) and a zero significand. This structure allows distinct +0 and -0 values, which are preserved during interconversions and certain operations to maintain numerical distinctions, particularly in financial and exact decimal computations. Unlike binary formats, the decimal representations leverage a base-10 significand, but the sign handling for zero remains analogous to ensure consistency across the standard. Historical formats like the IBM System/360 hexadecimal floating-point also support signed zero through a sign bit applied to an all-zero field for the exponent and fraction, resulting in +0 when the sign bit is 0 and -0 when it is 1. This representation, used in single-precision (32-bit) and double-precision (64-bit) modes, treats zero as a special case where the sign is retained. The format's base-16 significand and excess-64 exponent biasing do not alter the fundamental signed zero mechanism. In fixed-point arithmetic, signed zero is not typically distinguished, as these formats rely on integer representations (such as two's complement) where the all-zero bit pattern represents zero without a separate sign for zero values. For big integer and arbitrary-precision libraries, signed zero is rare and typically conceptual rather than distinct; in two's complement-based systems, -0 equals +0, but some sign-magnitude implementations (e.g., Java's BigInteger) assign a neutral signum of 0 to zero, avoiding a true signed distinction while allowing sign propagation in operations. Libraries like GMP normalize zero to a positive or unsigned state, but extensions in multiprecision floating-point contexts may track signed zeros for compatibility with behaviors.

Properties and operations

Notation and display

In mathematical notation, signed zeros are typically represented as +0 and -0 to distinguish the positive and negative variants, particularly in contexts where directional information is preserved, such as limits approaching zero from opposite sides. For instance, \lim_{x \to 0^+} \frac{1}{x} = +\infty and \lim_{x \to 0^-} \frac{1}{x} = -\infty, where the signed zero notation underscores the asymptotic behavior from the positive or negative direction. In programming languages adhering to IEEE 754, the display of signed zeros varies by implementation and formatting options. For example, in C and C++, the printf function with the %f specifier outputs -0.0 for negative zero, while %g outputs -0; similarly, Python's print(-0.0) renders -0.0 by default, though format specifiers like {:z g} (since Python 3.11) can normalize it to 0. The IEEE 754 standard does not prescribe specific textual output formats but emphasizes preserving the sign bit for zeros in representations and operations, recommending that debugging and scientific tools distinguish +0 from -0 to avoid obscuring directional information, such as in reciprocal operations where $1 / +0 = +\infty and $1 / -0 = -\infty. Historically, signed zero notation evolved in the 1970s with early floating-point formats like that of the DEC PDP-11, which used a sign-magnitude representation with a dedicated sign bit for the fraction, allowing zero to carry a sign (e.g., positive zero with sign bit 0 and all other bits zero, negative zero with sign bit 1); this convention influenced the IEEE 754 standard finalized in 1985, standardizing signed zeros across binary floating-point arithmetic.

Arithmetic behavior

In IEEE 754 floating-point arithmetic, signed zeros interact with addition and subtraction in ways that aim to maintain useful mathematical properties while adhering to rounding rules. The result of adding positive zero and negative zero, +0 + (-0), is +0 in the default round-to-nearest-ties-to-even mode, where the negative sign may be lost due to the tie-breaking preference for positive zero. However, subtraction can preserve the sign in certain cases; for instance, -0 - (+0) equals -0, as this is computed as -0 + (-(+0)) = -0 + (-0) = -0, with both operands sharing the negative sign. These behaviors ensure identities like x - x = +0 hold for all finite x, including zeros. Multiplication and division propagate the sign of signed zeros according to the standard sign rules of , treating zero results consistently with non-zero cases. For multiplication, a positive finite number times +0 yields +0, while the same number times -0 yields -0; the sign of the result is determined by the exclusive OR of the operands' signs. This rule applies even when one operand is zero: \operatorname{sign}(z) = \operatorname{sign}(x) \oplus \operatorname{sign}(y) where z = x \times y. Division follows analogous rules, such as (+0) divided by a negative finite number resulting in -0, preserving the sign to support identities like $1 / (1 / x) = x. Signed zeros are preserved in recommended functions to handle branch cuts and discontinuities correctly. The square root function returns \sqrt{-0} = -0, ensuring consistency along the negative real axis in complex extensions. Division by zero produces signed infinities: $1 / (+0) = +\infty and $1 / (-0) = -\infty, which reveals the divisor's sign. Transcendental functions, such as the natural logarithm, treat -0 as approaching from the negative side, yielding \log(-0) = -\infty to model the principal branch. Edge cases involving overflow and underflow also respect signed zeros and infinities. Underflow to zero inherits the sign from the exact result's direction, potentially producing +0 or -0 based on the operation. Overflow typically generates signed infinities with the sign matching the result's direction, such as positive overflow yielding +∞, while operations like finite times zero remain zero without overflow.

Comparison semantics

In the IEEE 754 standard for floating-point arithmetic, signed zeros are treated as equal under standard equality comparisons. Specifically, the equality predicate compareQuietEqual (and by extension, the = operator) returns true for +0 and -0, as comparisons ignore the sign of zero to ensure numerical consistency. However, bitwise comparisons or operations that examine the raw representation distinguish between them, since +0 and -0 have different sign bits. For ordering and relational operations, +0 is not less than -0 (i.e., +0 < -0 evaluates to false), and both are considered equal in magnitude with the sign disregarded in standard comparisons like <, >, <=, and >=. The standard provides a totalOrder predicate for a complete ordering of all floating-point values, where -0 precedes +0 (i.e., totalOrder(-0, +0) is true), preserving the sign's direction in extended models such as sorting or canonicalization. This distinction ensures that signed zeros can be ordered consistently when needed, though standard relational operators treat them interchangeably to avoid counterintuitive results in numerical computations. Signed zeros can introduce inconsistencies in sorting algorithms or databases if implementations rely solely on standard comparisons without accounting for the total order. For instance, naive may place +0 and -0 adjacently but unpredictably relative to other values, leading to non-deterministic outcomes across platforms; using the total order mitigates this by enforcing a strict sequence where -0 < +0. In programming languages like , which adhere to semantics, the strict equality operator === treats -0 and +0 as equal (e.g., -0 === 0 is true), but the Object.is method distinguishes them (e.g., Object.is(-0, 0) is false) to enable precise sign-aware comparisons.

Applications

In physical quantities

In physical measurements, signed zero plays a crucial role in preserving directional information when values round to zero, particularly for quantities like temperature where the sign indicates whether the measurement approached zero from below or above. For instance, in meteorology, air temperatures are often recorded to one-tenth of a degree and rounded to the nearest whole degree; a reading between -0.4°C and -0.1°C might round to -0°C to signify it was below freezing, while a reading between 0.1°C and 0.4°C rounds to +0°C to indicate it was slightly above, thus retaining the direction of approach without altering the numerical value to a generic zero. This concept extends to other physical quantities such as velocities or positions, where signed zero can represent a at rest while encoding the prior direction of motion—for example, - m/s for an object approaching a stop from the negative direction, or + m/s from the positive. In contexts, such as for motion tracking, this allows the sign to indicate the approached during or underflow, ensuring the aligns with the physical . The primary benefit of signed zero in these applications is its ability to maintain in physical models by avoiding artificial discontinuities at zero crossings; without it, could erase directional history, leading to errors in interpreting limits or gradients in quantities like or kinematic states. This preservation is especially valuable in gradual underflow scenarios, where small values transition smoothly without losing sign information. Real-world examples include thermometer readings in , where signed zero in digital displays or logs prevents the loss of sub-zero indications during borderline freezing events, and velocity sensors in automotive or , which use it to track directional cessation in low-speed maneuvers without resetting to unsigned zero.

In computational physics

In , signed zero is vital for ensuring numerical accuracy and stability in simulations that model physical limits, symmetries, and underflow conditions, where the sign of zero provides additional information about the direction from which a quantity approached zero. In fluid dynamics, signed zero enables the propagation of signs in conformal mapping techniques for modeling flows, such as liquid jets, where the sign of zero determines the correct attachment to branch cuts, maintaining continuity across boundaries in the simulation.

In programming and software

In C and C++, signed zeros are supported as part of compliance, with functions like std::copysign allowing the sign bit to be copied from one value to another, including for zeros, and std::signbit to test the sign of a value, returning a non-zero value for negative zero. These are defined in the , drawing from and requirements for floating-point operations. Python's math module provides math.copysign(x, y), which returns a float with the magnitude of x and the sign of y, explicitly preserving signed zeros on platforms that support them, such as math.copysign(1.0, -0.0) returning -1.0. Java's floating-point types (float and double) adhere to IEEE 754, representing both positive and negative zero, where they compare equal but differ in operations like division (e.g., 1.0 / -0.0 yields negative infinity). The strictfp modifier ensures strict conformance to IEEE 754 semantics across platforms by disabling extended-precision intermediates, thereby preserving signed zero behavior in arithmetic. In scientific computing libraries, NumPy's numpy.sign function returns 0 for zero inputs but normalizes negative zero to positive zero, losing the sign distinction. MATLAB's sign function similarly returns 0 for any zero input without distinguishing the sign, treating negative zero as positive zero in most operations. Best practices for signed zeros involve normalizing to positive zero (e.g., via addition to a positive value or explicit checks) when the sign carries no semantic meaning, such as in general scalar computations, to avoid unintended comparisons or outputs like -0.0. Preservation is recommended when the sign indicates directionality or underflow origin, for instance in graphics programming where vector components may use signed zero to maintain orientation in rendering pipelines. Historically, early compilers in the 1980s faced inconsistencies with signed zeros during the transition to adoption, as pre-standard systems on mainframes like CDC used sign-magnitude representations that could produce negative zeros, but compilers often failed to propagate or detect them correctly in arithmetic, leading to portability issues resolved by Fortran 90's IEEE alignment. Modern resolutions leverage standards, which mandate -compliant functions like copysign and signbit for consistent handling across systems.

References

  1. [1]
    IEEE Arithmetic
    IEEE 754 specifies exactly the single and double floating-point formats, and it defines a class of extended formats for each of these two basic formats. The ...
  2. [2]
    5.2. IEEE 754 Format - Intel
    Sign, Specifies the sign. 1 = negative, 0 = positive. Normal values, zero, infinity, and subnormals are all signed. NaN has no sign, so the S field is ignored.
  3. [3]
    Why computers have two floating point zeros: +0 and -0
    Jun 15, 2010 · The IEEE floating point standard says 1/+0 should be +infinity and 1/−0 should be -infinity. This makes sense if you interpret ± 0 as the ghost ...
  4. [4]
    IEEE Floating-Point Representation | Microsoft Learn
    Aug 3, 2021 · IEEE floating-point uses single (4-byte) and double (8-byte) formats. Single-precision has a sign bit, 8-bit exponent, and 23-bit significand.  ...
  5. [5]
    IEEE 754-2008 - IEEE SA
    Aug 29, 2008 · P754. Standard for Floating-Point Arithmetic. This standard specifies formats and operations for floating-point arithmetic in computer systems.
  6. [6]
    [PDF] IEEE Standard 754 for Binary Floating-Point Arithmetic
    Oct 1, 1997 · The leading bit is the sign bit, 0 for + and 1 for - . The next K+1 ... provide Quadruple-Precision correctly rounded in IEEE 754's style.
  7. [7]
    Milestones:IEEE Standard 754 for Binary Floating-Point Arithmetic ...
    IEEE 754 is a standard for dependable floating-point arithmetic, adopted by most since 1980, and has influenced processor designs and programming languages.
  8. [8]
    An Interview with the Old Man of Floating-Point - People @EECS
    Until the 1980s, almost all computers flushed underflows to zero and almost all programmers ignored them. In fact, Crays had no practical way to detect them and ...
  9. [9]
    754-2008 - IEEE Standard for Floating-Point Arithmetic
    Aug 29, 2008 · This standard specifies interchange and arithmetic formats and methods for binary and decimal floating-point arithmetic in computer ...
  10. [10]
    Floating-point numbers - IBM
    For hexadecimal floating-point operands, the implicit unit digit of the significand is always zero. Because the value if the significand and fraction are the ...
  11. [11]
    enthought/ibm2ieee: NumPy ufuncs for converting IBM-format ...
    Note that the IBM formats do not allow representations of special values like infinities and NaNs. However, signed zeros are representable, and the sign of a ...<|separator|>
  12. [12]
    Fixed-Point Arithmetic - MATLAB & Simulink - MathWorks
    The addition of fixed-point numbers requires that the binary points of the addends be aligned. The addition is then performed using binary arithmetic.
  13. [13]
    BigInteger (Java Platform SE 8 ) - Oracle Help Center
    The sign is represented as an integer signum value: -1 for negative, 0 for zero, or 1 for positive. The magnitude is a byte array in big-endian byte-order ...Missing: libraries | Show results with:libraries
  14. [14]
    The GNU MP Bignum Library
    GMP is a free library for arbitrary precision arithmetic, operating on signed integers, rational numbers, and floating-point numbers.GMP manual. · GMP Repository Usage · GMP 6.3 release notes
  15. [15]
    Is zero positive or negative? - Mathematics Stack Exchange
    Mar 13, 2011 · Sometimes for computational purposes, it may be necessary to consider signed zeros, that is, treating +0 and −0 as two different numbers.
  16. [16]
    How does your programming language handle “minus zero” (-0.0)?
    Mar 4, 2021 · It seems that programming languages handle these values in vastly different ways. The Python language it throws an exception when dividing by zero.
  17. [17]
    PEP 682 – Format Specifier for Signed Zero | peps.python.org
    Jan 29, 2022 · This PEP proposes an extension to the string format specification allowing negative zero to be normalized to positive zero.
  18. [18]
    [PDF] IEEE Standard 754 for Binary Floating-Point Arithmetic
    May 31, 1996 · Since 0.0 can have either sign, so can ∞; in fact, division by zero is the only algebraic operation that reveals the sign of zero. ( IEEE 754 ...
  19. [19]
    [PDF] PDP-11 Floating Point Format
    Nov 10, 1970 · These formats consist of a signed 7-bit exponent and a signed. 25 or 57 bit fraction with the quantity expressed by the number being the product ...
  20. [20]
  21. [21]
    Object.is() - JavaScript - MDN Web Docs - Mozilla
    Jul 10, 2025 · Object.is() is also not equivalent to the === operator. The only difference between Object.is() and === is in their treatment of signed zeros ...Try it · Syntax · Description · Examples
  22. [22]
    Here's Why Your Weather App Will Sometimes Put A Minus In Front ...
    Feb 22, 2022 · The reason for this is because of automation. In the field of meteorology we measure air temperature in tenths of a degree and then round to the nearest whole ...
  23. [23]
    [PDF] Branch Cuts for Complex Elementary Functions (or - FreeBSD
    The slit for arccosh, the only slit with a finite branch-point (-\) inside it, must be drawn along the real axis where z ~ +I.
  24. [24]
  25. [25]
  26. [26]
    math — Mathematical functions — Python 3.14.0 documentation
    On platforms that support signed zeros, copysign(1.0, -0.0) returns -1.0. Return the mantissa and exponent of x as the pair (m, e) .
  27. [27]
  28. [28]
  29. [29]
    None
    Nothing is retrieved...<|separator|>
  30. [30]
  31. [31]
    Floating-point rules (Direct3D 10) - Microsoft Learn
    Jan 6, 2021 · Some of these rules are a single option where IEEE-754 offers choices. Divide by 0 produces +/- INF, except 0/0 which results in NaN.
  32. [32]
    negative zero in fortran - Google Groups
    computers. The Fortran compiler and programs that ran on those machines could distinguish on input and save in memory two versions of zero, one of which was ...Missing: 1980s | Show results with:1980s
  33. [33]
    <math.h>
    ### Summary of `copysign` and `signbit` Regarding Signed Zero in POSIX Standard