Menu ▾ ▴

#5299 cf treats -c*sqrt(n) as +c*sqrt(n)

open
nobody
2026-09-27
2026-09-27
No

This bug was discovered by Claude Opus 5.5 and reproduced on Maxima Git commit c62924c (2026-09-26) with SBCL 2.2.9. Related: [#287].

Where: src/combin.lisp, CFEVAL

CFEVAL rewrites c*sqrt(n) as sqrt(c^2*n), which is valid only for c > 0, so a negative coefficient loses its sign. With c > 0 now required, other coefficients go through the general product code.

Steps

  1. Verify that the existing behavior is incorrect: run the reproducer below; it gives the result under "Before the fix". Judge for yourself that this is wrong instead of relying on the ticket: where the bug allows it, try some related inputs of your own, or check the result another way, for example numerically or against the documentation.
  2. Edit the file src/combin.lisp as described under "Fix".
  3. Rebuild Maxima.
  4. Verify that the behavior is now correct: the reproducer gives the result under "Correct result". Judge for yourself that this is right, not only that it matches: where the bug allows it, try some related inputs of your own, including some that the fix should leave unchanged.
  5. Add the test case(s) under "Test cases" to tests/rtest_numth.mac, at the end of the file.
  6. Run the complete test suite, share tests included (make check, or run_testsuite(share_tests=true); in ./maxima-local), and check that the change breaks no test. Failures that also occur without the change (a run on the unchanged build shows which) are pre-existing and can be ignored.
  7. Add the line * \#5299 cf treats -c*sqrt(n) as +c*sqrt(n) to ChangeLog, under "Bug fixes for numbered bugs:".
  8. Commit the fix; a proposed Git commit message is under "Commit message".
  9. Push the commit. Then set this ticket's status to "closed" and add a comment naming the commit, for example Fixed by commit [1a2b3c]., with the first six characters of the commit's SHA in the brackets (git rev-parse HEAD | cut -c1-6 prints them). SourceForge links this to the commit.

Reproducer

cf(3 - sqrt(3)); cf(-sqrt(3));

Before the fix:

[4, 1, 2] (about 4.73, the value of 3 + sqrt(3)); [1, 1, 2]

Correct result:

[1, 3] (3 - sqrt(3) is about 1.27); [-1, -1, -2]

Fix

In src/combin.lisp (CFEVAL, "(fixnump (cadr a))"), replace

                (fixnump (cadr a))
                (mexptp (caddr a))

with

                (fixnump (cadr a))
                (plusp (cadr a))
                (mexptp (caddr a))

The source file indents with tabs (8 columns); the code above shows them as spaces.

Test cases

Add these lines to tests/rtest_numth.mac, separated from the tests before them by two empty lines:

/* Bug #5299: "cf treats -c*sqrt(n) as +c*sqrt(n)" */

block([cflength: 1], [cf(-sqrt(3)), cf(3 - sqrt(3))]);
[[-1, -1, -2], [1, 3]]$

Commit message

cf(): keep the sign of c in c*sqrt(n)

CFEVAL rewrote c*sqrt(n) as sqrt(c^2*n), which holds only for c > 0, so
cf(-sqrt(3)) gave the continued fraction of sqrt(3) and cf(3 - sqrt(3))
that of 3 + sqrt(3). The shortcut now requires a positive c; other
coefficients go through the general product code.

This fixes bug #5299.

Found and fixed by Claude Opus 5.5.

Related

Bugs: #287

Discussion


Log in to post a comment.