hrv: state the real pct overflow bound, and pin that the wrap could land positive - #1688
Merged
Conversation
…and positive Follow-up to #1685, which widened HrvAnalyzer.pct correctly. Two things about it are worth getting exactly right, because the doc comments it added are what the next person will reason from. THE QUOTED BOUND IS THE WRONG ONE, AND IT UNDERSTATES THE EXPOSURE. Both comments say the overflow starts above 2147483647 / 200 = 10,737,418 ms. That is the bound for `part * 200` in isolation, but the numerator is `part * 200 + total`. Since part <= total, the numerator first exceeds Int.MAX_VALUE at total >= 10,683,999 (2147483647 / 201), about 53,000 ms lower and 2.97 h rather than 2.98 h. 10,737,418 is also the last value that does NOT overflow even for the multiply alone; that starts at 10,737,419. THE WRAP DID NOT ALWAYS LAND NEGATIVE. This is the half that matters. A 100% multi-share 8 h night, pct(28_800_000, 28_800_000), returned 25 in 32 bits: positive, plausible, and wrong by 75 points. So a negative multiMs was a symptom of the bug and never a test for it, and anyone re-reading pre-fix Android captures for #1008 / #1118 / #1331 / #1451 cannot filter on the sign. Every Android multiMs past the bound is suspect, including the ones that read fine. That is a stronger claim than the one the original made, and it changes how the existing logs should be treated. Comments on both platforms corrected, plus a twin test pinning the exact boundary and the readable-wrong case: 10,683,998 was still computed correctly in 32 bits, 10,683,999 wrapped to -100, 28,800,000 wrapped to 25. Verified rather than reasoned. Two independently written models of 32-bit truncation - one in Swift via the standalone oracle, one in Python - agree on all five values, and both reproduce the -16 the submitter's real 08-22 and 08-26 nights printed, which is what makes them worth trusting for the 25. The new test was falsified before being trusted: with pct reverted to Int arithmetic it fails expected:<100> but was:<-100> on the 10,683,999 case - a value the original comment described as safe, which is the correction, executable. Restored, 10 tests 0 failures, on freshly cleared result XMLs. python3 Tools/doc_comment_lint.py: OK, no new detached doc comments.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #1685, which widened
HrvAnalyzer.pctcorrectly. Two things about the doc comments itadded are worth getting exactly right, because they are what the next person reasons from.
1. The quoted bound is the wrong one, and it understates the exposure
Both comments say the overflow starts above
2147483647 / 200 = 10,737,418ms. That is the bound forpart * 200in isolation — but the numerator ispart * 200 + total. Sincepart <= total, itfirst exceeds
Int.MAX_VALUEattotal >= 10,683,999(2147483647 / 201): about 53,000 ms lower,and 2.97 h rather than 2.98 h.
10,737,418is also the last value that does not overflow even for the multiply alone — thatstarts at
10,737,419.2. The wrap did not always land negative — this is the half that matters
A 100% multi-share 8 h night returned 25: positive, plausible, and wrong by 75 points.
So a negative
multiMswas a symptom of this bug and never a test for it. Anyone re-readingpre-fix Android captures for #1008 / #1118 / #1331 / #1451 cannot filter on the sign — every Android
multiMspast the bound is suspect, including the ones that read fine. That is a stronger claimthan the original made, and it changes how the existing logs should be treated.
What changed
Comments corrected on both platforms, plus a twin test pinning the exact boundary and the
readable-wrong case:
No behaviour change:
pctitself is untouched, and all three assertions pass on both platforms today.They are a parity pin and a guard for
arm64_32, where the Kotlin failure reproduces exactly.How it was verified
Two independently written models of 32-bit truncation — one in Swift via the standalone oracle
(
swiftc -O twin.swift main.swift), one in Python — agree on all five values. Both also reproduce the-16that @Zebsi235's real 08-22 and 08-26 nights printed, which is what makes them worth trusting forthe
25.The new test was falsified before being trusted. With
pctreverted toIntarithmetic:on the
10,683,999case — a value the original comment described as safe. That is the correction,executable. Fix restored: 10 tests, 0 failures, on freshly cleared result XMLs.
python3 Tools/doc_comment_lint.py— OK, no new detached doc comments.swift testnot run locally (StrandAnalytics needs macOS via GRDB);swift-packages.ymlcovers it,and the asserted values come from the oracle rather than from reading the code.
Refs #1685. Docs and tests only — the arithmetic landed there and is unchanged here.