FAILURE MAP
← Case archive

FA-17146 / Floating-point arithmetic / Open access

Decimal notation strips significant trailing coefficient zeros · case 01

Decimal notation strips significant trailing coefficient zeros.

Verified by executionVariant 1 · 11 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

Decimal notation strips significant trailing coefficient zeros. The faulty expression is if len(coefficient)>leading: mantissa+="."+coefficient[leading:].rstrip("0").

VERIFIED REPAIR

Apply the contract at this fault site using if len(coefficient)>leading: mantissa+='.'+coefficient[leading:].

Unsuccessful approach: The attempted local correction if len(coefficient)>leading: mantissa+="."+str(int(coefficient[leading:])) still violates the explicit regression fixtures.

Case contract

Render a finite decimal text after half-even rounding to precision, in scientific or engineering notation. Preserve coefficient trailing zeros; engineering exponent is a multiple of three with one to three integer digits. Zero is canonical coefficient zero with original sign and exponent zero.

Why this case matters

An offline floating representation model isolates a reproducible arithmetic fault.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
import decimal
from decimal import Decimal, Context, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_DOWN

N = 1
observations = []
def solve(text,precision,engineering):
    ctx=Context(prec=precision,rounding=ROUND_HALF_EVEN)
    value=ctx.create_decimal(text)
    sign,digits,exponent=value.as_tuple()
    prefix='-' if sign else ''
    if value.is_zero(): return prefix+'0e0'
    coefficient=''.join(str(d) for d in digits)
    adjusted=len(coefficient)+exponent-1
    scale=(adjusted//3)*3 if engineering else adjusted
    leading=adjusted-scale+1
    coefficient=coefficient.ljust(leading,'0')
    mantissa=coefficient[:leading]
    if len(coefficient)>leading: mantissa+="."+coefficient[leading:].rstrip("0")
    return prefix+mantissa+'e'+str(scale)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('scientific carry', solve("999.5",3,False), "1.00e3")
check('engineering carry', solve("999.5",3,True), "1.00e3")
check('two integer digits', solve("12345",3,True), "12.3e3")
check('three integer digits', solve("123456",3,True), "123e3")
check('negative exponent', solve("0.01234",3,True), "12.3e-3")
check('scientific small', solve("0.01234",3,False), "1.23e-2")
check('padding', solve(str(N)+"e2",3,True), str(N)+"00e0")
check('negative coefficient', solve("-12345",3,False), "-1.23e4")
check('negative zero', solve("-0.00",3,False), "-0e0")
check('positive zero', solve("0.00",3,True), "0e0")
check('retained zeros', solve("1.200",4,False), "1.200e0")
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
scientific carry1.e31.00e3Failed
engineering carry1.e31.00e3Failed
two integer digits12.3e312.3e3Passed
three integer digits123e3123e3Passed
negative exponent12.3e-312.3e-3Passed
scientific small1.23e-21.23e-2Passed
padding100e0100e0Passed
negative coefficient-1.23e4-1.23e4Passed
negative zero-0e0-0e0Passed
positive zero0e00e0Passed
retained zeros1.2e01.200e0Failed

SHA-256 / 4bbc5b16e3ebc520b0b9f5662ed2eafb0420d89f8a99770d12b5abb6799ddb35

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
import decimal
from decimal import Decimal, Context, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_DOWN

N = 1
observations = []
def solve(text,precision,engineering):
    ctx=Context(prec=precision,rounding=ROUND_HALF_EVEN)
    value=ctx.create_decimal(text)
    sign,digits,exponent=value.as_tuple()
    prefix='-' if sign else ''
    if value.is_zero(): return prefix+'0e0'
    coefficient=''.join(str(d) for d in digits)
    adjusted=len(coefficient)+exponent-1
    scale=(adjusted//3)*3 if engineering else adjusted
    leading=adjusted-scale+1
    coefficient=coefficient.ljust(leading,'0')
    mantissa=coefficient[:leading]
    if len(coefficient)>leading: mantissa+="."+str(int(coefficient[leading:]))
    return prefix+mantissa+'e'+str(scale)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('scientific carry', solve("999.5",3,False), "1.00e3")
check('engineering carry', solve("999.5",3,True), "1.00e3")
check('two integer digits', solve("12345",3,True), "12.3e3")
check('three integer digits', solve("123456",3,True), "123e3")
check('negative exponent', solve("0.01234",3,True), "12.3e-3")
check('scientific small', solve("0.01234",3,False), "1.23e-2")
check('padding', solve(str(N)+"e2",3,True), str(N)+"00e0")
check('negative coefficient', solve("-12345",3,False), "-1.23e4")
check('negative zero', solve("-0.00",3,False), "-0e0")
check('positive zero', solve("0.00",3,True), "0e0")
check('retained zeros', solve("1.200",4,False), "1.200e0")
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
scientific carry1.0e31.00e3Failed
engineering carry1.0e31.00e3Failed
two integer digits12.3e312.3e3Passed
three integer digits123e3123e3Passed
negative exponent12.3e-312.3e-3Passed
scientific small1.23e-21.23e-2Passed
padding100e0100e0Passed
negative coefficient-1.23e4-1.23e4Passed
negative zero-0e0-0e0Passed
positive zero0e00e0Passed
retained zeros1.200e01.200e0Passed

SHA-256 / 9e0df5c3b2682e846c3f3b097101ee618361c1285ffa7edc5276c63f03ed154c

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json
import math
import decimal
from decimal import Decimal, Context, ROUND_HALF_EVEN, ROUND_HALF_UP, ROUND_DOWN

N = 1
observations = []
def solve(text,precision,engineering):
    ctx=Context(prec=precision,rounding=ROUND_HALF_EVEN)
    value=ctx.create_decimal(text)
    sign,digits,exponent=value.as_tuple()
    prefix='-' if sign else ''
    if value.is_zero(): return prefix+'0e0'
    coefficient=''.join(str(d) for d in digits)
    adjusted=len(coefficient)+exponent-1
    scale=(adjusted//3)*3 if engineering else adjusted
    leading=adjusted-scale+1
    coefficient=coefficient.ljust(leading,'0')
    mantissa=coefficient[:leading]
    if len(coefficient)>leading: mantissa+='.'+coefficient[leading:]
    return prefix+mantissa+'e'+str(scale)
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
check('scientific carry', solve("999.5",3,False), "1.00e3")
check('engineering carry', solve("999.5",3,True), "1.00e3")
check('two integer digits', solve("12345",3,True), "12.3e3")
check('three integer digits', solve("123456",3,True), "123e3")
check('negative exponent', solve("0.01234",3,True), "12.3e-3")
check('scientific small', solve("0.01234",3,False), "1.23e-2")
check('padding', solve(str(N)+"e2",3,True), str(N)+"00e0")
check('negative coefficient', solve("-12345",3,False), "-1.23e4")
check('negative zero', solve("-0.00",3,False), "-0e0")
check('positive zero', solve("0.00",3,True), "0e0")
check('retained zeros', solve("1.200",4,False), "1.200e0")
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
scientific carry1.00e31.00e3Passed
engineering carry1.00e31.00e3Passed
two integer digits12.3e312.3e3Passed
three integer digits123e3123e3Passed
negative exponent12.3e-312.3e-3Passed
scientific small1.23e-21.23e-2Passed
padding100e0100e0Passed
negative coefficient-1.23e4-1.23e4Passed
negative zero-0e0-0e0Passed
positive zero0e00e0Passed
retained zeros1.200e01.200e0Passed

SHA-256 / c421a992a6fd42590fcb32069f1fa06ed719cb80eba3fc3f3045dd9c8cb32870

Verification & scope

Controlled binary64 or explicitly stipulated miniature format; no hardware exception flags or platform floating environment are modeled. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:39:43.434159+00:00.

Case digest / 0fb6a452132b7cd1f7d3eedfe00f612d3d813c35eabd97576f0834ea9a56d35e