Skip to content

[P2] Recovery trace rounding diverges for signed zero and large finite values #47

Open

Description

@bhelm

Summary

The Swift and Kotlin Recovery trace rounding helpers still produce byte-different values for near-zero negatives and for large finite inputs.

This was found while reviewing the negative half-tie fix in #38. The Charge score is unaffected; only diagnostic trace formatting differs.

Minimal reproductions

Input to two-decimal helper Swift Kotlin
-0.004 -0.0 0.0
1e20 1e20 approximately 9.223372036854776e16
-1e20 -1e20 approximately -9.223372036854776e16

Cause

Swift performs floating-point rounding and preserves negative zero. Kotlin currently routes through Math.round, which returns a Long:

  • near-zero negatives become positive zero after division;
  • large finite values saturate at the signed-64 limits before division.

Impact

Recovery trace output is intended to be exactly comparable across platforms. The signed-zero case is reachable for small driver terms. The large-value case is not physiologically plausible, but the public trace API has no documented finite bounds.

Severity: P2 because the Recovery score is unchanged.

Acceptance criteria

  • Define one two-decimal trace-rounding contract for finite inputs.
  • Normalize signed zero identically.
  • Avoid platform-specific integer saturation, or explicitly reject/document inputs outside the supported range.
  • Add mirrored tests for -0.004, +0.004, ±1e20, ordinary non-ties and positive/negative half-ties.
  • Add an exact differential trace fixture in the Recovery rollout.

No hardware testing is required.

Activity

  1. bhelm commented on Aug 19, 2026

    @bhelm
    OwnerAuthor

    Upstream update: maintainer follow-up ryanbr#1446 merged as c593cba and fixes the reachable near-zero signed-zero trace divergence. The large finite Math.round/Long saturation cases remain unresolved, so this issue stays open with reduced scope.

  2. bhelm commented on Sep 7, 2026

    @bhelm
    OwnerAuthor

    PR opened upstream: ryanbr#1979 — the Kotlin trace rounding no longer routes through Math.round's
    Long, so large finite values stop saturating at 9.223372036854776e16 and match Swift; the four
    other Android sites with the same pattern are named there as a follow-up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions