FAILURE MAP
← Case archive

FA-84436 / Betting odds conversion / Open access

Power-method bisection moves the wrong bracket end · case 01

The power exponent converges to 1 or 10 and the fair probabilities do not sum to one.

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

ROOT CAUSE

The bisection sets hi when the powered sum is still above one.

VERIFIED REPAIR

Raise lo while the powered sum exceeds one.

Unsuccessful approach: Searching k on [0, 1] cannot reduce probabilities whose sum already exceeds one.

Case contract

Remove the bookmaker margin from decimal prices (implied p = 1/d, book = sum p > 1 assumed). multiplicative: p / book. additive: p - (book - 1) / n; if any result is negative return "additive infeasible". power: p ** k with k found by 60 bisection steps on [1, 10] so that the powered probabilities sum to 1 (k = midpoint of the final bracket). Any other method returns "invalid method". Return the fair probabilities formatted "%.4f".

Why this case matters

Pricing models strip margins differently; favourite-longshot bias makes the method matter.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(prices, method):
    ps = [1 / float(d) for d in prices]
    book = sum(ps)
    n = len(ps)
    if method == 'multiplicative':
        fair = [p / book for p in ps]
    elif method == 'additive':
        fair = [p - (book - 1) / n for p in ps]
        if any(x < 0 for x in fair):
            return 'additive infeasible'
    elif method == 'power':
        lo, hi = 1.0, 10.0
        for _ in range(60):
            mid = (lo + hi) / 2
            if sum(p ** mid for p in ps) > 1:
                hi = mid
            else:
                lo = mid
        k = (lo + hi) / 2
        fair = [p ** k for p in ps]
    else:
        return 'invalid method'
    return ['%.4f' % x for x in fair]
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 multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update', (['3.67', '1.10'], 'power'), ['0.1360', '0.8640']),
  ('variant scenario 1', (['1.16', '6.38'], 'power'), ['0.8562', '0.1438']),
  ('variant scenario 2', (['2.05', '14.07', '2.09'], 'additive'), ['0.4754', '0.0586', '0.4660'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update',
   (['5.55', '2.14', '2.00'], 'power'),
   ['0.1375', '0.4144', '0.4482']),
  ('variant scenario 1',
   (['2.01', '2.51', '6.12', '10.10'], 'additive'),
   ['0.4579', '0.3588', '0.1238', '0.0594']),
  ('variant scenario 2', (['1.57', '1.97'], 'shin'), 'invalid method')],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update',
   (['6.44', '3.05', '2.57', '6.36'], 'power'),
   ['0.1488', '0.3196', '0.3808', '0.1507']),
  ('variant scenario 1',
   (['2.82', '5.29', '5.54', '2.56'], 'additive'),
   ['0.3259', '0.1603', '0.1518', '0.3619']),
  ('variant scenario 2', (['1.27', '11.62', '4.64'], 'shin'), 'invalid method')],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update',
   (['2.85', '3.58', '3.18', '8.34'], 'power'),
   ['0.3331', '0.2622', '0.2969', '0.1079']),
  ('variant scenario 1', (['1.68', '4.49', '3.51'], 'additive'), ['0.5610', '0.1884', '0.2506']),
  ('variant scenario 2', (['2.30', '1.48'], 'additive'), ['0.3796', '0.6204'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update',
   (['3.00', '5.62', '3.12', '2.96'], 'power'),
   ['0.2887', '0.1420', '0.2762', '0.2931']),
  ('variant scenario 1',
   (['2.72', '54.78', '4.16', '2.80', '6.54'], 'multiplicative'),
   ['0.3235', '0.0161', '0.2115', '0.3143', '0.1346']),
  ('variant scenario 2',
   (['4.03', '4.17', '5.00', '12.68', '4.10'], 'power'),
   ['0.2458', '0.2374', '0.1978', '0.0775', '0.2415'])]]
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 fixtureActualExpectedOutcome
control multiplicative['0.5263', '0.4737']['0.5263', '0.4737']Passed
control additive['0.5278', '0.4722']['0.5278', '0.4722']Passed
control power['0.0028', '0.0010']['0.5285', '0.4715']Failed
boundary additive longshotadditive infeasibleadditive infeasiblePassed
boundary unknown methodinvalid methodinvalid methodPassed
regression: power bracket update['0.0000', '0.3855']['0.1360', '0.8640']Failed
variant scenario 1['0.2267', '0.0000']['0.8562', '0.1438']Failed
variant scenario 2['0.4754', '0.0586', '0.4660']['0.4754', '0.0586', '0.4660']Passed

SHA-256 / 4480d183e5414768e05c87ca4f5d106063d93234a309243fba99d77c4a2ac1e9

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(prices, method):
    ps = [1 / float(d) for d in prices]
    book = sum(ps)
    n = len(ps)
    if method == 'multiplicative':
        fair = [p / book for p in ps]
    elif method == 'additive':
        fair = [p - (book - 1) / n for p in ps]
        if any(x < 0 for x in fair):
            return 'additive infeasible'
    elif method == 'power':
        lo, hi = 0.0, 1.0
        for _ in range(60):
            mid = (lo + hi) / 2
            if sum(p ** mid for p in ps) > 1:
                lo = mid
            else:
                hi = mid
        k = (lo + hi) / 2
        fair = [p ** k for p in ps]
    else:
        return 'invalid method'
    return ['%.4f' % x for x in fair]
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 multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update', (['3.67', '1.10'], 'power'), ['0.1360', '0.8640']),
  ('variant scenario 1', (['1.16', '6.38'], 'power'), ['0.8562', '0.1438']),
  ('variant scenario 2', (['2.05', '14.07', '2.09'], 'additive'), ['0.4754', '0.0586', '0.4660'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update',
   (['5.55', '2.14', '2.00'], 'power'),
   ['0.1375', '0.4144', '0.4482']),
  ('variant scenario 1',
   (['2.01', '2.51', '6.12', '10.10'], 'additive'),
   ['0.4579', '0.3588', '0.1238', '0.0594']),
  ('variant scenario 2', (['1.57', '1.97'], 'shin'), 'invalid method')],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update',
   (['6.44', '3.05', '2.57', '6.36'], 'power'),
   ['0.1488', '0.3196', '0.3808', '0.1507']),
  ('variant scenario 1',
   (['2.82', '5.29', '5.54', '2.56'], 'additive'),
   ['0.3259', '0.1603', '0.1518', '0.3619']),
  ('variant scenario 2', (['1.27', '11.62', '4.64'], 'shin'), 'invalid method')],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update',
   (['2.85', '3.58', '3.18', '8.34'], 'power'),
   ['0.3331', '0.2622', '0.2969', '0.1079']),
  ('variant scenario 1', (['1.68', '4.49', '3.51'], 'additive'), ['0.5610', '0.1884', '0.2506']),
  ('variant scenario 2', (['2.30', '1.48'], 'additive'), ['0.3796', '0.6204'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update',
   (['3.00', '5.62', '3.12', '2.96'], 'power'),
   ['0.2887', '0.1420', '0.2762', '0.2931']),
  ('variant scenario 1',
   (['2.72', '54.78', '4.16', '2.80', '6.54'], 'multiplicative'),
   ['0.3235', '0.0161', '0.2115', '0.3143', '0.1346']),
  ('variant scenario 2',
   (['4.03', '4.17', '5.00', '12.68', '4.10'], 'power'),
   ['0.2458', '0.2374', '0.1978', '0.0775', '0.2415'])]]
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 fixtureActualExpectedOutcome
control multiplicative['0.5263', '0.4737']['0.5263', '0.4737']Passed
control additive['0.5278', '0.4722']['0.5278', '0.4722']Passed
control power['0.5556', '0.5000']['0.5285', '0.4715']Failed
boundary additive longshotadditive infeasibleadditive infeasiblePassed
boundary unknown methodinvalid methodinvalid methodPassed
regression: power bracket update['0.2725', '0.9091']['0.1360', '0.8640']Failed
variant scenario 1['0.8621', '0.1567']['0.8562', '0.1438']Failed
variant scenario 2['0.4754', '0.0586', '0.4660']['0.4754', '0.0586', '0.4660']Passed

SHA-256 / 5e59dc26f4de37ea2814e36dca6cf8162412cc4e0e7347152fbe4b5b21b82aee

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(prices, method):
    ps = [1 / float(d) for d in prices]
    book = sum(ps)
    n = len(ps)
    if method == 'multiplicative':
        fair = [p / book for p in ps]
    elif method == 'additive':
        fair = [p - (book - 1) / n for p in ps]
        if any(x < 0 for x in fair):
            return 'additive infeasible'
    elif method == 'power':
        lo, hi = 1.0, 10.0
        for _ in range(60):
            mid = (lo + hi) / 2
            if sum(p ** mid for p in ps) > 1:
                lo = mid
            else:
                hi = mid
        k = (lo + hi) / 2
        fair = [p ** k for p in ps]
    else:
        return 'invalid method'
    return ['%.4f' % x for x in fair]
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 multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update', (['3.67', '1.10'], 'power'), ['0.1360', '0.8640']),
  ('variant scenario 1', (['1.16', '6.38'], 'power'), ['0.8562', '0.1438']),
  ('variant scenario 2', (['2.05', '14.07', '2.09'], 'additive'), ['0.4754', '0.0586', '0.4660'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update',
   (['5.55', '2.14', '2.00'], 'power'),
   ['0.1375', '0.4144', '0.4482']),
  ('variant scenario 1',
   (['2.01', '2.51', '6.12', '10.10'], 'additive'),
   ['0.4579', '0.3588', '0.1238', '0.0594']),
  ('variant scenario 2', (['1.57', '1.97'], 'shin'), 'invalid method')],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update',
   (['6.44', '3.05', '2.57', '6.36'], 'power'),
   ['0.1488', '0.3196', '0.3808', '0.1507']),
  ('variant scenario 1',
   (['2.82', '5.29', '5.54', '2.56'], 'additive'),
   ['0.3259', '0.1603', '0.1518', '0.3619']),
  ('variant scenario 2', (['1.27', '11.62', '4.64'], 'shin'), 'invalid method')],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update',
   (['2.85', '3.58', '3.18', '8.34'], 'power'),
   ['0.3331', '0.2622', '0.2969', '0.1079']),
  ('variant scenario 1', (['1.68', '4.49', '3.51'], 'additive'), ['0.5610', '0.1884', '0.2506']),
  ('variant scenario 2', (['2.30', '1.48'], 'additive'), ['0.3796', '0.6204'])],
 [('control multiplicative', (['1.80', '2.00'], 'multiplicative'), ['0.5263', '0.4737']),
  ('control additive', (['1.80', '2.00'], 'additive'), ['0.5278', '0.4722']),
  ('control power', (['1.80', '2.00'], 'power'), ['0.5285', '0.4715']),
  ('boundary additive longshot',
   (['1.01', '15.00', '100.00', '100.00'], 'additive'),
   'additive infeasible'),
  ('boundary unknown method', (['1.80', '2.00'], 'shin'), 'invalid method'),
  ('regression: power bracket update',
   (['3.00', '5.62', '3.12', '2.96'], 'power'),
   ['0.2887', '0.1420', '0.2762', '0.2931']),
  ('variant scenario 1',
   (['2.72', '54.78', '4.16', '2.80', '6.54'], 'multiplicative'),
   ['0.3235', '0.0161', '0.2115', '0.3143', '0.1346']),
  ('variant scenario 2',
   (['4.03', '4.17', '5.00', '12.68', '4.10'], 'power'),
   ['0.2458', '0.2374', '0.1978', '0.0775', '0.2415'])]]
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 fixtureActualExpectedOutcome
control multiplicative['0.5263', '0.4737']['0.5263', '0.4737']Passed
control additive['0.5278', '0.4722']['0.5278', '0.4722']Passed
control power['0.5285', '0.4715']['0.5285', '0.4715']Passed
boundary additive longshotadditive infeasibleadditive infeasiblePassed
boundary unknown methodinvalid methodinvalid methodPassed
regression: power bracket update['0.1360', '0.8640']['0.1360', '0.8640']Passed
variant scenario 1['0.8562', '0.1438']['0.8562', '0.1438']Passed
variant scenario 2['0.4754', '0.0586', '0.4660']['0.4754', '0.0586', '0.4660']Passed

SHA-256 / 3e95fa1b777c4741f951f64429bf4a9540867ec22e5046e9c2a1269366e90cbe

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.941542+00:00.

Case digest / a27665ca27b2a1ee24f3eeb578d4035481bbe73f0a82e0ce6c2d3ce9fad09c96