Skip to content

Widen ln 2 by x's integer digits in Exp2 [patch] - #140

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/exp2-ln2-guard-digits-123
Sep 30, 2026
Merged

matt-edmondson merged 1 commit into
mainfrom
fix/exp2-ln2-guard-digits-123

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #123

What changed

Exp2(x, d) read ln 2 at a fixed d + ExponentialGuardDigits digits. Multiplying by x scales the absolute error in ln 2 by |x|. Once x has about ten integer digits the guard digits are used up, and the last requested digit rounds the wrong way. ln 2 is now widened by IntegerDigitCount(x), which is what Exp2M1 already does.

Exp10 was checked for the same pattern and does not have it: it splits off the whole power of ten before it multiplies by ln 10, so the series only ever sees a fraction in [0, 1).

Tests

TestExp2RoundsTheLastDigitOfALargeFractionalPower covers both rows from the issue. It compares significand and exponent directly, because ToString on these exponents runs out of memory:

  • Exp2(7000000000.5, 3) → 629e2107209967 (was 628e…)
  • Exp2(-6000000000.5, 5) → 73383e-1806179979 (was 73384e…)

Each case is also checked against Exp2(x, d + 40).ReduceSignificance(d). The test failed on main (expected 629, actual 628) and passes with the fix. The full suite passes: 435 of 435.

🤖 Generated with Claude Code

https://claude.ai/code/session_014jNTPLxThrQnZyafw1CZ1p


Generated by Claude Code

Exp2 read ln 2 at a fixed significantDigits + guard digits. Multiplying
by x scales that error by |x|, so a fractional power with about ten
integer digits rounded its last digit wrong. Widen ln 2 by the integer
digits of x, as Exp2M1 already does. Exp10 splits off its whole part
first and does not have the problem.

Fixes #123

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014jNTPLxThrQnZyafw1CZ1p
@sonarqubecloud

Copy link
Copy Markdown

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.

Exp2 rounds the last digit wrong for non-integer x with a large integer part, because ln 2 isn't widened by x's magnitude

2 participants