FAILURE MAP
← Case archive

FA-84461 / Betting odds conversion / Open access

Negative Asian prices rounded toward positive infinity · case 01

A -0.125 Malay price shows "-1.88" or "-0.12" instead of "-0.13".

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

ROOT CAUSE

The helper rounds the signed value with floor(x + 1/2) and splits cents with floor division.

VERIFIED REPAIR

Round the magnitude half away from zero and prefix the sign.

Unsuccessful approach: Using round() on the magnitude rounds exact halves to even.

Case contract

Convert a decimal price (> 1, else "invalid") to an Asian odds style. hk: d - 1. malay: d - 1 when d <= 2, else -1 / (d - 1). indo: d - 1 when d >= 2, else -1 / (d - 1). Other styles return "invalid style". Values are rounded half away from zero to two decimals and formatted with a leading "-" for negatives.

Why this case matters

Asian-facing sportsbooks show Hong Kong, Malay and Indonesian prices with sign conventions.

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, style):
    def fmt(x):
        c = math.floor(x * 100 + Fraction(1, 2))
        return '%d.%02d' % (c // 100, c % 100)
    d = Fraction(decimal)
    if d <= 1:
        return 'invalid'
    if style == 'hk':
        v = d - 1
    elif style == 'malay':
        v = d - 1 if d <= 2 else -1 / (d - 1)
    elif style == 'indo':
        v = d - 1 if d >= 2 else -1 / (d - 1)
    else:
        return 'invalid style'
    return fmt(v)
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 hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('2.25', 'malay'), '-0.80'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('1.80', 'malay'), '0.80'),
  ('variant scenario 2', ('9.00', 'indo'), '8.00')],
 [('control hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('1.00', 'malay'), 'invalid'),
  ('variant scenario 2', ('2.25', 'us'), 'invalid style')],
 [('control hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('1.75', 'indo'), '-1.33'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('2.00', 'indo'), '1.00'),
  ('variant scenario 2', ('1.919', 'hk'), '0.92')],
 [('control hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('3.64', 'malay'), '-0.38'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('9.00', 'hk'), '8.00'),
  ('variant scenario 2', ('9.00', 'us'), 'invalid style')],
 [('control hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('2.665', 'malay'), '-0.60'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('1.00', 'indo'), 'invalid'),
  ('variant scenario 2', ('1.80', 'hk'), '0.80')]]
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 hong kong0.850.85Passed
control malay positive0.800.80Passed
control malay negative-1.20-0.80Failed
boundary malay evens1.001.00Passed
control indo negative-2.75-1.25Failed
boundary indo half rounds away-1.88-0.13Failed
regression: negative rounding-1.20-0.80Failed
regression: negative rounding-1.88-0.13Failed
variant scenario 10.800.80Passed
variant scenario 28.008.00Passed

SHA-256 / e34f2eb79dd433d067e8de5441cc3b95ebed541e6ffe6603125084ef4ef3e899

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, style):
    def fmt(x):
        sign = '-' if x < 0 else ''
        c = round(abs(x) * 100)
        return sign + '%d.%02d' % (c // 100, c % 100)
    d = Fraction(decimal)
    if d <= 1:
        return 'invalid'
    if style == 'hk':
        v = d - 1
    elif style == 'malay':
        v = d - 1 if d <= 2 else -1 / (d - 1)
    elif style == 'indo':
        v = d - 1 if d >= 2 else -1 / (d - 1)
    else:
        return 'invalid style'
    return fmt(v)
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 hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('2.25', 'malay'), '-0.80'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('1.80', 'malay'), '0.80'),
  ('variant scenario 2', ('9.00', 'indo'), '8.00')],
 [('control hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('1.00', 'malay'), 'invalid'),
  ('variant scenario 2', ('2.25', 'us'), 'invalid style')],
 [('control hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('1.75', 'indo'), '-1.33'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('2.00', 'indo'), '1.00'),
  ('variant scenario 2', ('1.919', 'hk'), '0.92')],
 [('control hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('3.64', 'malay'), '-0.38'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('9.00', 'hk'), '8.00'),
  ('variant scenario 2', ('9.00', 'us'), 'invalid style')],
 [('control hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('2.665', 'malay'), '-0.60'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('1.00', 'indo'), 'invalid'),
  ('variant scenario 2', ('1.80', 'hk'), '0.80')]]
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 hong kong0.850.85Passed
control malay positive0.800.80Passed
control malay negative-0.80-0.80Passed
boundary malay evens1.001.00Passed
control indo negative-1.25-1.25Passed
boundary indo half rounds away-0.12-0.13Failed
regression: negative rounding-0.80-0.80Passed
regression: negative rounding-0.12-0.13Failed
variant scenario 10.800.80Passed
variant scenario 28.008.00Passed

SHA-256 / 53a660b1e0e2ffbc4d6321803e8a54e3a4201a3c4c746d4185efcf2d61b79fea

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, style):
    def fmt(x):
        sign = '-' if x < 0 else ''
        c = math.floor(abs(x) * 100 + Fraction(1, 2))
        return sign + '%d.%02d' % (c // 100, c % 100)
    d = Fraction(decimal)
    if d <= 1:
        return 'invalid'
    if style == 'hk':
        v = d - 1
    elif style == 'malay':
        v = d - 1 if d <= 2 else -1 / (d - 1)
    elif style == 'indo':
        v = d - 1 if d >= 2 else -1 / (d - 1)
    else:
        return 'invalid style'
    return fmt(v)
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 hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('2.25', 'malay'), '-0.80'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('1.80', 'malay'), '0.80'),
  ('variant scenario 2', ('9.00', 'indo'), '8.00')],
 [('control hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('1.00', 'malay'), 'invalid'),
  ('variant scenario 2', ('2.25', 'us'), 'invalid style')],
 [('control hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('1.75', 'indo'), '-1.33'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('2.00', 'indo'), '1.00'),
  ('variant scenario 2', ('1.919', 'hk'), '0.92')],
 [('control hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('3.64', 'malay'), '-0.38'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('9.00', 'hk'), '8.00'),
  ('variant scenario 2', ('9.00', 'us'), 'invalid style')],
 [('control hong kong', ('1.85', 'hk'), '0.85'),
  ('control malay positive', ('1.80', 'malay'), '0.80'),
  ('control malay negative', ('2.25', 'malay'), '-0.80'),
  ('boundary malay evens', ('2.00', 'malay'), '1.00'),
  ('control indo negative', ('1.80', 'indo'), '-1.25'),
  ('boundary indo half rounds away', ('9.00', 'malay'), '-0.13'),
  ('regression: negative rounding', ('2.665', 'malay'), '-0.60'),
  ('regression: negative rounding', ('9.00', 'malay'), '-0.13'),
  ('variant scenario 1', ('1.00', 'indo'), 'invalid'),
  ('variant scenario 2', ('1.80', 'hk'), '0.80')]]
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 hong kong0.850.85Passed
control malay positive0.800.80Passed
control malay negative-0.80-0.80Passed
boundary malay evens1.001.00Passed
control indo negative-1.25-1.25Passed
boundary indo half rounds away-0.13-0.13Passed
regression: negative rounding-0.80-0.80Passed
regression: negative rounding-0.13-0.13Passed
variant scenario 10.800.80Passed
variant scenario 28.008.00Passed

SHA-256 / 8242579a4c0825ebd00d223bc3c9f5b1193d3838c05c9c8d5b0ce69b1b282c06

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

Case digest / 152c84359315d1d482babcfd1354d5188f9a16b41343b3a245babaf7305567e3