FA-84361 / Betting odds conversion / Open access
Decimal price parsed as a binary float · case 01
Prices exactly on a half-dollar boundary round the wrong way.
ROOT CAUSE
The price text is parsed with float(), so 2.005 becomes 2.00499999...
VERIFIED REPAIR
Parse the decimal text exactly.
Unsuccessful approach: Rounding the float to two decimals first cannot restore the lost half-cent.
Case contract
Convert a decimal price string to an American moneyline string. Prices at or below 1 return "invalid". For d >= 2 the line is "+" followed by 100 * (d - 1); for d < 2 it is "-" followed by 100 / (d - 1). The magnitude is computed exactly from the decimal text and rounded half up to an integer. Evens (2.00) is "+100".
Why this case matters
Sportsbooks display the same price in decimal and American formats and must agree at every boundary.
1 / The failure
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
import math
N = 1
observations = []
def solve(decimal):
d = float(decimal)
if d <= 1:
return 'invalid'
if d >= 2:
v = (d - 1) * 100
sign = '+'
else:
v = 100 / (d - 1)
sign = '-'
n = math.floor(v + Fraction(1, 2))
return sign + str(n)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
try:
return solve(*args)
except Exception as exc:
return 'raised ' + type(exc).__name__
cases = [[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('6.99',), '+599'),
('variant scenario 2', ('2.75',), '+175')],
[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('3.125',), '+213'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('2.951',), '+195'),
('variant scenario 2', ('6.21',), '+521')],
[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('14.74',), '+1374'),
('variant scenario 2', ('1.00',), 'invalid')],
[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('3.125',), '+213'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('13.57',), '+1257'),
('variant scenario 2', ('10.35',), '+935')],
[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('2.125',), '+113'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('5.20',), '+420'),
('variant scenario 2', ('8.76',), '+776')]]
for label, args, expected in cases[N - 1]:
check(label, run(args), expected)
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 |
|---|---|---|---|
| control underdog | +150 | +150 | Passed |
| control favourite | -200 | -200 | Passed |
| boundary evens | +100 | +100 | Passed |
| boundary half-cent rounds up | +100 | +101 | Failed |
| boundary no-profit price | invalid | invalid | Passed |
| control short favourite | -1250 | -1250 | Passed |
| regression: binary float parse | +100 | +101 | Failed |
| variant scenario 1 | +599 | +599 | Passed |
| variant scenario 2 | +175 | +175 | Passed |
SHA-256 / b31c01fef78bc73cef39ebf9a26864516bb67143ef214d623ef075971c24fae2
2 / The unsuccessful fix
Exit 1"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
import math
N = 1
observations = []
def solve(decimal):
d = round(float(decimal), 2)
if d <= 1:
return 'invalid'
if d >= 2:
v = (d - 1) * 100
sign = '+'
else:
v = 100 / (d - 1)
sign = '-'
n = math.floor(v + Fraction(1, 2))
return sign + str(n)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
try:
return solve(*args)
except Exception as exc:
return 'raised ' + type(exc).__name__
cases = [[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('6.99',), '+599'),
('variant scenario 2', ('2.75',), '+175')],
[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('3.125',), '+213'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('2.951',), '+195'),
('variant scenario 2', ('6.21',), '+521')],
[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('14.74',), '+1374'),
('variant scenario 2', ('1.00',), 'invalid')],
[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('3.125',), '+213'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('13.57',), '+1257'),
('variant scenario 2', ('10.35',), '+935')],
[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('2.125',), '+113'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('5.20',), '+420'),
('variant scenario 2', ('8.76',), '+776')]]
for label, args, expected in cases[N - 1]:
check(label, run(args), expected)
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 |
|---|---|---|---|
| control underdog | +150 | +150 | Passed |
| control favourite | -200 | -200 | Passed |
| boundary evens | +100 | +100 | Passed |
| boundary half-cent rounds up | +100 | +101 | Failed |
| boundary no-profit price | invalid | invalid | Passed |
| control short favourite | -1250 | -1250 | Passed |
| regression: binary float parse | +100 | +101 | Failed |
| variant scenario 1 | +599 | +599 | Passed |
| variant scenario 2 | +175 | +175 | Passed |
SHA-256 / f8183c77a081d4e7fd75c8344e9a476baf3020d6683cf57380bcef785044a852
3 / The verified repair
Exit 0"""Failure Map reference implementation. Python standard library only."""
import json
from fractions import Fraction
import math
N = 1
observations = []
def solve(decimal):
d = Fraction(decimal)
if d <= 1:
return 'invalid'
if d >= 2:
v = (d - 1) * 100
sign = '+'
else:
v = 100 / (d - 1)
sign = '-'
n = math.floor(v + Fraction(1, 2))
return sign + str(n)
def check(label, actual, expected):
observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
def run(args):
try:
return solve(*args)
except Exception as exc:
return 'raised ' + type(exc).__name__
cases = [[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('6.99',), '+599'),
('variant scenario 2', ('2.75',), '+175')],
[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('3.125',), '+213'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('2.951',), '+195'),
('variant scenario 2', ('6.21',), '+521')],
[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('14.74',), '+1374'),
('variant scenario 2', ('1.00',), 'invalid')],
[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('3.125',), '+213'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('13.57',), '+1257'),
('variant scenario 2', ('10.35',), '+935')],
[('control underdog', ('2.50',), '+150'),
('control favourite', ('1.50',), '-200'),
('boundary evens', ('2.00',), '+100'),
('boundary half-cent rounds up', ('2.005',), '+101'),
('boundary no-profit price', ('1.00',), 'invalid'),
('control short favourite', ('1.08',), '-1250'),
('regression: binary float parse', ('2.125',), '+113'),
('regression: binary float parse', ('2.005',), '+101'),
('variant scenario 1', ('5.20',), '+420'),
('variant scenario 2', ('8.76',), '+776')]]
for label, args, expected in cases[N - 1]:
check(label, run(args), expected)
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 |
|---|---|---|---|
| control underdog | +150 | +150 | Passed |
| control favourite | -200 | -200 | Passed |
| boundary evens | +100 | +100 | Passed |
| boundary half-cent rounds up | +101 | +101 | Passed |
| boundary no-profit price | invalid | invalid | Passed |
| control short favourite | -1250 | -1250 | Passed |
| regression: binary float parse | +101 | +101 | Passed |
| variant scenario 1 | +599 | +599 | Passed |
| variant scenario 2 | +175 | +175 | Passed |
SHA-256 / 3e139fafbf41b39ce97902fed96b941bfcbcd840739da14b3975a7969d1ec61e
Verification & scope
Stipulated, bounded toy contract stated in the contract field; not a claim of conformance with any operator, exchange or regulator rule set. 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:50:30.248740+00:00.
Case digest / eebb1c87e2088c44b4e10e950efd6e3a27485ae435b508b004d62417ed39b062