Skip to content

Round lat/lon in executor JSON output to avoid IEEE-754 float noise #1

Description

@kiki830621

Chain pre-flight: diagnosis bypassed

  • At: 2026-05-29T06:27:26Z by /idd-all-chain
  • User choice: proceed anyway despite no separate diagnosis comment
  • Rationale: issue body already contains root cause (raw Double → JSONSerialization 17-sig-digit rendering) + fix strategy (round to 6 dp) + the 4 affected executors. Spec is not vague; the chain's internal idd-diagnose has a concrete target.

Problem

Original text (from test-coverage session, 2026-05-28):
「executor 把 lat/lon 用 raw Double 丟給 JSONSerialization25.04 會渲染成 25.039999999999999(IEEE-754 noise),影響所有吐座標的 executor(bus/bike/traffic/parking)。對 LLM 消費無害(它會 round),但不乾淨。真要修是在 executor 把座標 round 到 ~6 位小數(≈0.1m,遠夠交通用)。已在 d49eecb commit message + 測試註解記錄,留待未來 polish。」

Geo-emitting executors build their output dictionaries with raw Double
latitude/longitude values and hand them to JSONSerialization. Because
25.04 is not exactly representable in IEEE-754 binary64, the serializer
emits the full 17-significant-digit form 25.039999999999999 rather than
the clean 25.04 the source TDX data implies.

Confirmed empirically during the test-coverage work (commit d49eecb):

JSONSerialization.data(withJSONObject: ["lat": 25.04, "lon": 121.56])
=> {"lat":25.039999999999999,"lon":121.56}

(Note 121.56 happens to render cleanly — representability is value-dependent,
so the noise appears unpredictably across coordinates.)

Type

refactor (output is numerically correct, just not clean — no functional bug)

Expected

Coordinate fields in tool output render at a sane precision, e.g.
"lat":25.04, with no 17-digit float tail.

Actual

Coordinates render with IEEE-754 noise, e.g. "lat":25.039999999999999,
whenever the value is not exactly representable in binary64.

Affected executors

Every executor that emits lat / lon (or nested position) from a
RailPosition-shaped Double pair:

  • bus_status_positionsBusLivePosition.busPosition
  • bike_search_stations / bike_stations_nearby — station StationPosition
  • traffic_cctv — CCTV Position
  • parking_list_lotsCarParkPosition

Impact

Cosmetic. An LLM consuming the JSON rounds it when presenting to the user,
so end-user-visible behavior is unaffected. The noise is just ugly in the
raw tool output and in any logging / debugging that inspects it.

Suggested fix

Round coordinates to ~6 decimal places (about 0.1 m, far finer than any
transit use needs) before they enter the output dictionary. Options:

  1. A small helper roundCoord(_ d: Double) -> Double { (d * 1e6).rounded() / 1e6 }
    applied at each dict["lat"] = ... / dict["lon"] = ... site.
  2. A shared output-assembly helper that all geo-emitting executors call,
    centralizing the rounding in one place.

Option 2 is preferable if the rounding is the only shared concern; option 1
if a shared helper would be over-abstraction for four call sites.

Provenance

Documented in commit d49eecb (executor test coverage) message + the
testBusStatusPositionsAssemblesPositions test note, which asserts on the
stable leading digits ("lat":25.0) precisely because of this noise.

Metadata

Metadata

Assignees

No one assigned

    Labels

    refactorCode change that neither fixes a bug nor adds a feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions