FA-17116 / Floating-point arithmetic / Open access
Decimal notation lays out unrounded coefficient digits · case 01
Decimal notation lays out unrounded coefficient digits.
ROOT CAUSE
Decimal notation lays out unrounded coefficient digits. The faulty expression is value=Decimal(text).
VERIFIED REPAIR
Apply the contract at this fault site using value=ctx.create_decimal(text).
Unsuccessful approach: The attempted local correction value=Decimal(str(float(text))) 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=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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| scientific carry | 9.995e2 | 1.00e3 | Failed |
| engineering carry | 999.5e0 | 1.00e3 | Failed |
| two integer digits | 12.345e3 | 12.3e3 | Failed |
| three integer digits | 123.456e3 | 123e3 | Failed |
| negative exponent | 12.34e-3 | 12.3e-3 | Failed |
| scientific small | 1.234e-2 | 1.23e-2 | Failed |
| padding | 100e0 | 100e0 | Passed |
| negative coefficient | -1.2345e4 | -1.23e4 | Failed |
| negative zero | -0e0 | -0e0 | Passed |
| positive zero | 0e0 | 0e0 | Passed |
| retained zeros | 1.200e0 | 1.200e0 | Passed |
SHA-256 / 69d9d86341ba2cc4d04e850e7873f01a79d4ae0bb458db7d5e4953dfe4c91311
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=Decimal(str(float(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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| scientific carry | 9.995e2 | 1.00e3 | Failed |
| engineering carry | 999.5e0 | 1.00e3 | Failed |
| two integer digits | 12.3450e3 | 12.3e3 | Failed |
| three integer digits | 123.4560e3 | 123e3 | Failed |
| negative exponent | 12.34e-3 | 12.3e-3 | Failed |
| scientific small | 1.234e-2 | 1.23e-2 | Failed |
| padding | 100.0e0 | 100e0 | Failed |
| negative coefficient | -1.23450e4 | -1.23e4 | Failed |
| negative zero | -0e0 | -0e0 | Passed |
| positive zero | 0e0 | 0e0 | Passed |
| retained zeros | 1.2e0 | 1.200e0 | Failed |
SHA-256 / b023cf55abb024d82f30e0e9cfc7aebe889195914571459702e171fad4988903
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 fixture | Actual | Expected | Outcome |
|---|---|---|---|
| scientific carry | 1.00e3 | 1.00e3 | Passed |
| engineering carry | 1.00e3 | 1.00e3 | Passed |
| two integer digits | 12.3e3 | 12.3e3 | Passed |
| three integer digits | 123e3 | 123e3 | Passed |
| negative exponent | 12.3e-3 | 12.3e-3 | Passed |
| scientific small | 1.23e-2 | 1.23e-2 | Passed |
| padding | 100e0 | 100e0 | Passed |
| negative coefficient | -1.23e4 | -1.23e4 | Passed |
| negative zero | -0e0 | -0e0 | Passed |
| positive zero | 0e0 | 0e0 | Passed |
| retained zeros | 1.200e0 | 1.200e0 | Passed |
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.025564+00:00.
Case digest / 8f8c22956774befa7b66b09f7a652656f8feb7d32ff8d83f38b94cb36bcb5410