Skip to content

v2.1.0: Round-to-nearest accuracy fixes and release automation#9

Merged
GeEom merged 6 commits into
mainfrom
rounding_accuracy
Jul 6, 2026
Merged

v2.1.0: Round-to-nearest accuracy fixes and release automation#9
GeEom merged 6 commits into
mainfrom
rounding_accuracy

Conversation

@GeEom

@GeEom GeEom commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Rounding instead of truncation at two systematic bias points

Circular CORDIC table angles:

  • from_i1f63 truncates, biasing every converted angle low by up to one ulp
  • Circular vectoring now rounds table angles to nearest at the lookup, via a private kernel helper (no trait or API changes)
  • Hyperbolic vectoring deliberately keeps truncation: rounding its table regresses atanh/ln/acoth, indicating a datapath bias that the truncated angles partially cancel — documented in the kernel as future work

exp argument reduction and scaling:

  • Reduction now computes k = floor(x/ln2) instead of trunc, keeping r ∈ [0, ln2) so exp(r) carries a full significand in [1, 2) into the final shift
  • The scaling right-shift for negative k rounds to nearest instead of truncating toward −∞, which matters most where the true result is only a few ulps

Accuracy improvements:

  • exp: 1.9× mean, 1.9× P95 (I16F16); 2.0× mean, 2.0× P95 (I32F32)
  • pow2: 2.0× mean, 2.0× P95 (both types)
  • atan: 1.8× mean (I16F16), 1.2× (I32F32)
  • asin/acos: 1.55× mean (I16F16), 1.2× (I32F32)
  • All other functions unchanged (byte-identical results)

Saturation threshold changes:

  • exp zero threshold: −11.1 → ~−11.8 (I16F16), −22.2 → ~−22.9 (I32F32)
  • pow2 zero threshold: −16.1 → ~−17.1 (I16F16), −32.1 → ~−33.1 (I32F32)
  • Results just past the old cutoffs now correctly round to one ulp instead of truncating to zero

Toolchain and dependencies:

  • MSRV raised from 1.88 to 1.95 (current stable); MSRV CI job and README updated
  • fixed dependency floor moved to 1.31 (requires rustc 1.93+); byte-identical accuracy results, and its new unsafe unchecked_* methods are unused since this crate denies unsafe_code

Release automation:

  • Publish now runs on push to main: when Cargo.toml's version is absent from the crates.io sparse index it tests, tags, publishes, and creates the GitHub release in a single run
  • Replaces the tag-triggered flow, which could not be driven by an automated tag push (events created with the default GITHUB_TOKEN do not trigger other workflows — the reason the old auto-tag chain never fired)
  • Every step is idempotent; failed runs can be retried from the Actions tab, and version-unchanged merges release nothing
  • Merging this PR is the first live run: v2.1.0 publishes automatically on merge

No public API changes. Baseline and README regenerated; no-panic verification passes.

GeEom added 4 commits July 6, 2026 10:06
from_i1f63 truncates, biasing every converted angle low by up to one
ulp. Circular vectoring's accumulated z is dominated by this table
quantization, so a round-to-nearest conversion at the lookup improves
asin/acos/atan means 1.2-1.8x with all other functions unchanged.

Hyperbolic vectoring keeps the truncating conversion deliberately:
rounding its table regresses atanh/ln/acoth, indicating a datapath
bias that the truncated angles partially cancel. Documented in the
helper for future kernel work.
Two truncation biases fixed. The reduction now computes
k = floor(x / ln2) instead of trunc, keeping r in [0, ln2) so exp(r)
carries a full significand in [1, 2) into the final scaling. The
scaling right-shift for negative k now rounds to nearest instead of
truncating toward zero, which matters most where the true result is
only a few ulps.

Halves mean, median, and P95 relative error for exp and pow2 on both
I16F16 and I32F32 (exp I16F16 mean 1.14e-2 -> 5.98e-3, P95
7.88e-2 -> 4.13e-2).

The zero-saturation threshold moves accordingly: results now round to
one ulp rather than truncating to zero just past the old cutoff
(I16F16: ~-11.1 -> ~-11.8; I32F32: ~-22.2 -> ~-22.9; pow2 similar).
Docs and threshold tests updated.
Raises MSRV from 1.88 to the current stable and moves the fixed
dependency floor to 1.31 (which itself requires rustc 1.93+). No
functional changes: fixed 1.31.0 produces byte-identical accuracy
results, and the 1.31 additions (unsafe unchecked_* methods) are
unused since this crate denies unsafe_code.

Updates the MSRV CI job, README requirement line, and the stale
install-snippet version.
@GeEom GeEom mentioned this pull request Jul 6, 2026
The old flow chained auto-tag.yml (tag on merge) into publish.yml
(publish on tag). Tags pushed with the default GITHUB_TOKEN
deliberately do not trigger other workflows, so the chain never fired
and tags had to be deleted and re-pushed by hand to release.

Publish now runs on push to main: when Cargo.toml's version is absent
from the crates.io sparse index it tests, tags, publishes, and creates
the GitHub release in a single run. The tag is an output of the run
rather than its trigger, so no PAT is required. All steps are
idempotent and a failed run can be retried from the Actions tab.
@GeEom GeEom changed the title v2.1.0: Round-to-nearest conversions and exp reduction fix v2.1.0: Round-to-nearest accuracy fixes and release automation Jul 6, 2026
@GeEom GeEom closed this Jul 6, 2026
@GeEom GeEom reopened this Jul 6, 2026
@codecov-commenter

codecov-commenter commented Jul 6, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 81.57895% with 7 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/ops/exponential.rs 74.07% 7 Missing ⚠️

📢 Thoughts on this report? Let us know!

Adds tests for the two genuinely untested new paths: the exp
floor-adjustment band where the truncated quotient sits exactly at
-max_shift (x ~ -21.6 at I16F16, ~ -43.7 at I32F32), and the exact
i1f63 conversion for types with 63+ fractional bits (I64F64 CORDIC).

Collapses exp's three-way scale match into if/else so the
shr_rounded(x, 0) identity path is exercised by every scale == 0
call instead of being an unreachable guard.

Raises codecov targets to match measured coverage (96.2%): project
80% -> 95%, patch 80% -> 85%, badge range 90...100. The remaining
flagged lines are tarpaulin attribution artifacts (inlined const fns,
attribute lines, and a block provably executed by exp(-1)).
@GeEom GeEom merged commit 234d3b1 into main Jul 6, 2026
12 checks passed
@GeEom GeEom deleted the rounding_accuracy branch July 6, 2026 09:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants