Skip to content

Claude Opus 5.5 (effort default (no --effort flag) · thinking on) on Make invoice maths exact: half-up line rounding, per-rate VAT, largest-remainder allocation, banker's FX rounding

AClaude Opus 5.5default · thinking on · Claude Code 2.1.299 (headless -p) · cloud · 2026-10-17 · by @bobsiopener

Trust 80%Fully autonomoussuccess · first try
Estimated cost
$0.28
Wall time
1m
Human step-ins
0
Outcome
Pass

Compare with other models on this task →

Summary

Exact prompt

# Task: make the invoice maths exact `money.py` uses binary floats and produces off-by-a-cent results. Fix it so these rules hold exactly (inputs and outputs are decimal strings; keep the function names and signatures): **All functions:** every returned amount is a string with exactly the target currency's decimals (e.g. "0.00", "-1.50", "1200" for JPY, "1.001" for BHD). Never output a negative zero such as "-0.00": a zero is always unsigned. `currency`/`to_currency` default to EUR where shown. **invoice(lines, currency)** - Line net = price x qty x (1 - discount_pct/100), rounded **half-up** (away from zero on .5) to the currency's decimals (EUR/USD 2, JPY 0, BHD 3). `qty` may be fractional, `discount_pct` is optional (default 0). Negative prices (credit lines) are allowed: half-up means 0.5 rounds away from zero for them too. - `net` = sum of rounded line nets. VAT is computed **per VAT rate** on that rate's summed rounded nets and rounded half-up. `vat` maps each rate string exactly as given (e.g. "20", "5.5") to its amount, in first-appearance order. `gross` = net + sum of VAT amounts. **allocate(amount, weights, currency)** - Split `amount` in proportion to non-negative integer `weights` (at least one positive) so that the parts sum **exactly** to amount: floor each exact share to the smallest unit (toward negative infinity for negative amounts — i.e. compute on the absolute value and re-apply the sign), then hand out remaining smallest units one each to the parts with the largest remainders; ties (equal remainders) go to the lower index. Example: `allocate("0.05", [3, 7])` -> `["0.02", "0.03"]` (exact shares 1.5 and 3.5 cents, equal remainders, the extra cent goes to index 0). Zero weight gets zero. Raise `ValueError` if all weights are 0. **convert(amount, rate, to_currency)** - amount x rate, rounded **half-even** (banker's) to the target decimals. Standard library only. No network.

Float classics (1.005, 2.675), half-up for negatives, VAT on grouped rounded nets, -0.00 suppression, 0/2/3-decimal currencies, deterministic largest-remainder tie-breaks and half-even conversion all have exact expected strings. Original benchmark task written for usecaserank.com (not based on a specific public post). Headless, offline run on a reproducible fixture. Each run's notes say how its cost was measured (estimates are marked).

Success criteria: 1. All 9 hidden unittest cases pass: half-up line rounding incl. float traps, discount + fractional qty, VAT grouping and order, credit lines and no '-0.00', JPY/BHD decimals, empty invoice, allocation (ties, zero weights, negatives, ValueError), allocation sums exactly, half-even conversion.

Setup notes: Use Case Scout batch 6 case f04-money-precision (offline fixture). Prepared with batch6/prepare.sh; hidden key/tests kept outside the agent's work dir. Prompt = TASK.md verbatim. Scored with the scout's scorer: `python score.py WORKDIR KEYDIR`. Tools: Read/Write/Edit/Glob/Grep/Bash, web disabled. Single run, no retries. Claude Code's own reported cost for claude-opus-5.5: $0.276388. Score: 9/9. Cost is an ESTIMATE: measured tokens x pricing.json list price (Claude Pro subscription, nothing billed); input_tokens include cache reads and writes. Single run.

Estimated cost List-price estimate; not actually billed.

Metrics

Estimated cost
$0.28
Wall time
1m
Human step-ins
0
Turns
11
Model usage
ModelInput tokOutput tokCost
AClaude Opus 5.5anthropic/claude-opus-5.5effort default (no --effort flag) · thinking on179,5016,364$0.28

Reproduce this run

  1. Use the use case prompt on the use case page.
  2. Same setup: Claude Opus 5.5 (anthropic/claude-opus-5.5, effort default (no --effort flag) · thinking on) via Claude Code 2.1.299 (headless -p), cloud.
  3. It counts as a success only if it meets every success criterion: 1. All 9 hidden unittest cases pass: half-up line rounding incl. float traps, discount + fractional qty, VAT grouping and order, credit lines and no '-0.00', JPY/BHD decimals, empty invoice, allocation (ties, zero weights, negatives, ValueError), allocation sums exactly, half-even conversion.
  4. Log model, tokens, wall time, human step-ins and the evidence log, then submit it as a reproduction. A different model? Submit a head-to-head rerun.

How runs are scored: Methodology.

Was this useful?

⇄ Rerun on another model

Automated checks

Trust 80% comes from these checks (how Trust % works).

Evidence log
[
 {
  "duration_api_ms": 69529,
  "stop_reason": "end_turn",
  "session_id": "[REDACTED]",
  "total_cost_usd": 0.2763878,
  "usage": {
   "input_tokens": 16,
   "cache_creation_input_tokens": 14506,
   "cache_read_input_tokens": 164979,
   "output_tokens": 6364,
   "output_tokens_details": {
    "thinking_tokens": 1062
   },
   "server_tool_use": {
    "web_search_requests": 0,
    "web_fetch_requests": 0
   },
   "service_tier": "standard",
   "cache_creation": {
    "ephemeral_1h_input_tokens": 14506,
    "ephemeral_5m_input_tokens": 0
   },
   "inference_geo": "global",
   "iterations": [
    {
     "input_tokens": 2,
     "output_tokens": 997,
     "cache_read_input_tokens": 25410,
     "cache_creation_input_tokens": 1242,
     "cache_creation": {
      "ephemeral_5m_input_tokens": 0,
      "ephemeral_1h_input_tokens": 1242
     },
     "type": "message"
    }
   ],
   "speed": "standard",
   "fallback_credit": null
  },
  "modelUsage": {
   "claude-opus-5-5": {
    "inputTokens": 16,
    "outputTokens": 6364,
    "cacheReadInputTokens": 164979,
    "cacheCreationInputTokens": 14506,
    "webSearchRequests": 0,
    "costUSD": 0.2763878,
    "contextWindow": 1000000,
    "maxOutputTokens": 128000,
    "thinkingTokens": 1062,
    "canonicalModel": "claude-opus-5-5",
    "provider": "firstParty",
    "costBasis": "list"
   }
  },
  "permission_denials": [],
  "terminal_reason": "completed",
  "fast_mode_state": "off",
  "fast_mode_disabled_reason": "sdk_opt_in_required",
  "subagent_stats": {
   "spawned": 0,
   "requested": {
    "background": 0,
    "foreground": 0,
    "unset": 0
   },
   "started_in_background": 0,
   "max_depth": 0,
   "spawned_by_subagents": 0,
   "completed": 0,
   "failed": 0,
   "killed": {
    "parent": 0,
    "user": 0,
    "system": 0
   },
   "refused": {
    "depth_limit": 0,
    "concurrency_limit": 0,
    "budget": 0
   },
   "by_type": {}
  },
  "safety_stops": 0,
  "is_error": false,
  "num_turns": 11,
  "subtype": "success",
  "api_error_status": null,
  "result": "I rewrote `money.py` to do all the maths exactly, with no floats. The function names and signatures are unchanged and it uses only the standard library. I tested it with a one-off script (not saved), and every result matched the rules when I worked it out by hand.\n\n**How it works**\n- **Exact arithmetic:** calculations use Python's `Decimal` type, set up so that any accidental rounding raises an error instead of passing silently. Rounding only happens at the steps your rules name: each line net and each VAT amount round half-up, and `convert` rounds half-even.\n- **Splitting (`allocate`):** the amount is turned into a whole number of smallest units (cents, fils, yen) and split by the \"largest remainder\" rule on its absolute value, then the sign is put back. Ties go to the lower index.\n- **Output:** every amount has exactly the currency's number of decimals, and a zero is never shown as negative (`-0.00` becomes `0.00`).\n\n**Results from the test run**\n- The docstring example (2.675 \u00d7 3, 10% discount, 20% VAT) gives net 7.22, VAT 1.44, gross 8.66.\n- A credit line of \u22120.005 rounds to \u22120.01 (away from zero), and VAT is worked out separately for each rate (\"20\" and \"5.5\" kept as given, in order).\n- JPY 1199.5 gives \"1200\" and BHD 1.0005 gives \"1.001\". A tiny credit like \u22120.004 gives \"0.00\", not \"-0.00\".\n- `allocate(\"0.05\", [3, 7])` gives `[\"0.02\", \"0.03\"]`, and `allocate(\"100\", [1, 1, 1])` gives `[\"33.34\", \"33.33\", \"33.33\"]`. Zero weights get zero, and all-zero weights raise `ValueError`.\n- `convert` rounds half-even: 1.005 \u2192 1.00, 1.015 \u2192 1.02, and 2.5 JPY \u2192 2.\n\n**Two behaviours your rules didn't cover**\n- **Amounts with too many decimals:** `allocate` raises `ValueError` if the amount has more decimals than the currency allows (e.g. \"0.005\" in EUR), because those parts couldn't add up exactly to the amount.\n- **Invalid weights:** `allocate` also raises `ValueError` for negative weights or weights that aren't integers.\n\n**Negative amounts in `allocate`:** your rules say \"toward negative infinity\" but also say to work on the absolute value and re-apply the sign. Those disagree for negative amounts, and I followed the absolute-value method. So `allocate(\"-0.05\", [3, 7])` gives `[\"-0.02\", \"-0.03\"]`, which still adds up exactly to the amount.",
  "ttft_ms": 2468,
  "type": "result",
  "duration_ms": 70021,
  "uuid": "[REDACTED]",
  "ttft_stream_ms": 1538,
  "time_to_request_ms": 240,
  "first_content_frame_ms": 1538,
  "queued_turn_count": 0,
  "result_index": 0
 }
]

Get new runs and ranking changes weekly