Batu Lab NotesPractical developer guides

Preserve or collapse Decimal signed zero by an explicit display policy

By Batu · English technical notes

Also published in our primary archive.

Python Decimal negative zero should be displayed according to an explicit policy because its sign is observable even though it compares equal to positive zero. If formatting logic only checks equality, Decimal('-0.00') == Decimal('0.00') is true and the business decision about whether to retain a meaningful negative sign is hidden.

The example starts with the two source values and records is_zero() and is_signed() for each. Both are zero; only -0.00 is signed. It then applies two small display functions. preserve_sign uses the Decimal’s fixed-point formatting, which retains the minus sign and scale. collapse_zero deliberately maps every zero to a new positive Decimal with the same exponent before formatting. Thus it renders both zero inputs as 0.00 while leaving nonzero values unchanged.

Neither policy is universally correct. Preserve the sign when it carries useful provenance, such as the direction of a rounded adjustment. Collapse it when the display contract says users should see a single zero representation. Keep the policy at the presentation boundary; changing the stored Decimal would discard information. This example’s assertions demonstrate observations and output for these two values, not a general financial-display standard. The is_zero, is_signed, and as_tuple APIs are available in Python 3.4 and later.

The Decimal.is_zero and Decimal.is_signed documentation define these classification methods, while Decimal.as_tuple documents the representation that includes the sign.

AI assistance disclosure: This article was prepared with AI assistance and checked with the shown synthetic example.

from decimal import Decimal

values = [Decimal("-0.00"), Decimal("0.00")]

def preserve_sign(value):
    return format(value, "f")

def collapse_zero(value):
    if value.is_zero():
        value = Decimal((0, (0,), value.as_tuple().exponent))
    return format(value, "f")

matrix = [
    (str(value), value.is_zero(), value.is_signed(),
     preserve_sign(value), collapse_zero(value))
    for value in values
]

assert values[0] == values[1]
assert matrix == [
    ("-0.00", True, True, "-0.00", "0.00"),
    ("0.00", True, False, "0.00", "0.00"),
]

for row in matrix:
    print(" | ".join(map(str, row)))
-0.00 | True | True | -0.00 | 0.00
0.00 | True | False | 0.00 | 0.00