FAILURE MAP
← Case archive

FA-90231 / Bytecode virtual machines / Open access

Numeric for loop: float limits truncated toward zero · case 01

for i = -5, -2.5 runs to -2, one iteration past the limit.

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

ROOT CAUSE

The float limit is converted with int(), which truncates instead of rounding toward the loop start.

THE FAILURE

The float limit is converted with int(), which truncates instead of rounding toward the loop start.

Unsuccessful approach: Always flooring makes descending loops stop one value early.

Case contract

Numeric for-loop preparation (Lua-style FORPREP/FORLOOP). A zero step is an error. With integer init and step, a float limit is floored for positive steps and ceiled for negative ones; the loop is skipped when init is already past the limit in the step direction; otherwise the iteration count (limit - init) // step is precomputed (for negative steps (init - limit) // -step) and the loop runs count + 1 times. Otherwise the loop uses floats and re-tests v <= limit (v >= limit for negative steps). Return at most the first 20 control values.

Why this case matters

Loop-preparation opcodes must precompute counts exactly to avoid off-by-one and overflow bugs.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(init, limit, step):
    if step == 0:
        return 'error: for step is zero'
    if isinstance(init, int) and isinstance(step, int):
        if isinstance(limit, float):
            limit = int(limit)
        if (step > 0 and init > limit) or (step < 0 and init < limit):
            return []
        count = (limit - init) // step if step > 0 else (init - limit) // (-step)
        out = []
        v = init
        for _ in range(min(count, 19) + 1):
            out.append(v)
            v += step
        return out
    out = []
    v = float(init)
    while (v <= limit if step > 0 else v >= limit) and len(out) < 20:
        out.append(v)
        v += step
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: ascending integer loop', (1, 4, 1), [1, 2, 3, 4]),
  ('descending loop with remainder', (11, 1, -3), [11, 8, 5, 2]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -3.5, 1), [-5, -4]),
  ('float limit ceils for descending loops', (6, 2.5, -1), [6, 5, 4, 3]),
  ('init equal to limit runs once', (1, 1, 1), [1]),
  ('descending init equal to limit runs once', (1, 1, -1), [1]),
  ('long loop is capped at 20 values',
   (0, 101, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 6, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 5, 1), [1, 2, 3, 4, 5]),
  ('descending loop with remainder', (12, 1, -3), [12, 9, 6, 3]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -4.5, 1), [-5]),
  ('float limit ceils for descending loops', (7, 2.5, -1), [7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (2, 2, 1), [2]),
  ('descending init equal to limit runs once', (2, 2, -1), [2]),
  ('long loop is capped at 20 values',
   (0, 102, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 7, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 6, 1), [1, 2, 3, 4, 5, 6]),
  ('descending loop with remainder', (13, 1, -3), [13, 10, 7, 4, 1]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -5.5, 1), []),
  ('float limit ceils for descending loops', (8, 2.5, -1), [8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (3, 3, 1), [3]),
  ('descending init equal to limit runs once', (3, 3, -1), [3]),
  ('long loop is capped at 20 values',
   (0, 103, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 8, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 7, 1), [1, 2, 3, 4, 5, 6, 7]),
  ('descending loop with remainder', (14, 1, -3), [14, 11, 8, 5, 2]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -6.5, 1), []),
  ('float limit ceils for descending loops', (9, 2.5, -1), [9, 8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (4, 4, 1), [4]),
  ('descending init equal to limit runs once', (4, 4, -1), [4]),
  ('long loop is capped at 20 values',
   (0, 104, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 9, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 8, 1), [1, 2, 3, 4, 5, 6, 7, 8]),
  ('descending loop with remainder', (15, 1, -3), [15, 12, 9, 6, 3]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -7.5, 1), []),
  ('float limit ceils for descending loops', (10, 2.5, -1), [10, 9, 8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (5, 5, 1), [5]),
  ('descending init equal to limit runs once', (5, 5, -1), [5]),
  ('long loop is capped at 20 values',
   (0, 105, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 10, 0), 'error: for step is zero')]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*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
regression: ascending integer loop[1, 2, 3, 4][1, 2, 3, 4]Passed
descending loop with remainder[11, 8, 5, 2][11, 8, 5, 2]Passed
descending loop with odd step[7, 5, 3, 1][7, 5, 3, 1]Passed
float limit floors for ascending loops[-5, -4, -3][-5, -4]Failed
float limit ceils for descending loops[6, 5, 4, 3, 2][6, 5, 4, 3]Failed
init equal to limit runs once[1][1]Passed
descending init equal to limit runs once[1][1]Passed
long loop is capped at 20 values[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19][0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]Passed
float loop reaches its limit exactly[1.0, 0.75, 0.5, 0.25, 0.0][1.0, 0.75, 0.5, 0.25, 0.0]Passed
control: zero steperror: for step is zeroerror: for step is zeroPassed

SHA-256 / eb9d2c99f5eef7a26a8493265ec27edb5eeb23e9f2f6b55223bb24931e54f045

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json
import math
N = 1
observations = []
def solve(init, limit, step):
    if step == 0:
        return 'error: for step is zero'
    if isinstance(init, int) and isinstance(step, int):
        if isinstance(limit, float):
            limit = math.floor(limit)
        if (step > 0 and init > limit) or (step < 0 and init < limit):
            return []
        count = (limit - init) // step if step > 0 else (init - limit) // (-step)
        out = []
        v = init
        for _ in range(min(count, 19) + 1):
            out.append(v)
            v += step
        return out
    out = []
    v = float(init)
    while (v <= limit if step > 0 else v >= limit) and len(out) < 20:
        out.append(v)
        v += step
    return out
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
cases = [[('regression: ascending integer loop', (1, 4, 1), [1, 2, 3, 4]),
  ('descending loop with remainder', (11, 1, -3), [11, 8, 5, 2]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -3.5, 1), [-5, -4]),
  ('float limit ceils for descending loops', (6, 2.5, -1), [6, 5, 4, 3]),
  ('init equal to limit runs once', (1, 1, 1), [1]),
  ('descending init equal to limit runs once', (1, 1, -1), [1]),
  ('long loop is capped at 20 values',
   (0, 101, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 6, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 5, 1), [1, 2, 3, 4, 5]),
  ('descending loop with remainder', (12, 1, -3), [12, 9, 6, 3]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -4.5, 1), [-5]),
  ('float limit ceils for descending loops', (7, 2.5, -1), [7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (2, 2, 1), [2]),
  ('descending init equal to limit runs once', (2, 2, -1), [2]),
  ('long loop is capped at 20 values',
   (0, 102, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 7, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 6, 1), [1, 2, 3, 4, 5, 6]),
  ('descending loop with remainder', (13, 1, -3), [13, 10, 7, 4, 1]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -5.5, 1), []),
  ('float limit ceils for descending loops', (8, 2.5, -1), [8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (3, 3, 1), [3]),
  ('descending init equal to limit runs once', (3, 3, -1), [3]),
  ('long loop is capped at 20 values',
   (0, 103, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 8, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 7, 1), [1, 2, 3, 4, 5, 6, 7]),
  ('descending loop with remainder', (14, 1, -3), [14, 11, 8, 5, 2]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -6.5, 1), []),
  ('float limit ceils for descending loops', (9, 2.5, -1), [9, 8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (4, 4, 1), [4]),
  ('descending init equal to limit runs once', (4, 4, -1), [4]),
  ('long loop is capped at 20 values',
   (0, 104, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 9, 0), 'error: for step is zero')],
 [('regression: ascending integer loop', (1, 8, 1), [1, 2, 3, 4, 5, 6, 7, 8]),
  ('descending loop with remainder', (15, 1, -3), [15, 12, 9, 6, 3]),
  ('descending loop with odd step', (7, 0, -2), [7, 5, 3, 1]),
  ('float limit floors for ascending loops', (-5, -7.5, 1), []),
  ('float limit ceils for descending loops', (10, 2.5, -1), [10, 9, 8, 7, 6, 5, 4, 3]),
  ('init equal to limit runs once', (5, 5, 1), [5]),
  ('descending init equal to limit runs once', (5, 5, -1), [5]),
  ('long loop is capped at 20 values',
   (0, 105, 1),
   [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
  ('float loop reaches its limit exactly', (1.0, 0.0, -0.25), [1.0, 0.75, 0.5, 0.25, 0.0]),
  ('control: zero step', (1, 10, 0), 'error: for step is zero')]]
for label, args, expected in cases[N - 1]:
    check(label, solve(*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
regression: ascending integer loop[1, 2, 3, 4][1, 2, 3, 4]Passed
descending loop with remainder[11, 8, 5, 2][11, 8, 5, 2]Passed
descending loop with odd step[7, 5, 3, 1][7, 5, 3, 1]Passed
float limit floors for ascending loops[-5, -4][-5, -4]Passed
float limit ceils for descending loops[6, 5, 4, 3, 2][6, 5, 4, 3]Failed
init equal to limit runs once[1][1]Passed
descending init equal to limit runs once[1][1]Passed
long loop is capped at 20 values[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19][0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]Passed
float loop reaches its limit exactly[1.0, 0.75, 0.5, 0.25, 0.0][1.0, 0.75, 0.5, 0.25, 0.0]Passed
control: zero steperror: for step is zeroerror: for step is zeroPassed

SHA-256 / 8583572d14c236899b2f0cbf0ca73cd7252cd6a80daaa2a07df269bf1f667654

HELD IN THE MEMBER ARCHIVE

The verified repair and its recorded checks are member-only.

This mechanism has 10 recorded checks per implementation. The open-access tier publishes the failure and the unsuccessful fix; the repaired source that passes every check, and the observations that prove it, are available to members.

Every case sharing this mechanism uses the same contract and the same repair, so this one record is held back for all of them.

Member access is invitation-based. Sign in with your invited account to inspect the repair.

Sign in to the archive ↗

Verification & scope

A deterministic, bounded teaching model of one bytecode virtual machine mechanism with a stipulated instruction encoding; it is not a production VM and claims no conformance to any real specification. 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:51:25.031872+00:00.

Case digest / f9b9b61e83620d99ae7308defe5187030e149846e2e9d2db5fc95668f177b39a