Skip to content

Fix squareRoot returning overestimates (squareRoot(6) = 3) - #2250

Open
devladpopov wants to merge 1 commit into
trekhleb:masterfrom
devladpopov:fix/square-root-stop-condition
Open

devladpopov wants to merge 1 commit into
trekhleb:masterfrom
devladpopov:fix/square-root-stop-condition

Conversation

@devladpopov

Copy link
Copy Markdown

Fixes #2231

The loop stopped once |number - root^2| <= 10^-tolerance. That bounds the error of the square, not of the root, so Newton's method could stop on an overestimate and the final rounding made it visible:

call before after
squareRoot(6) 3 2
squareRoot(12) 4 3
squareRoot(3, 1) 1.8 1.7

Change: starting from 1, after the first Newton step the approximation is never below the root (AM-GM) and every next step moves it down. So the loop now runs while the approximation keeps decreasing, which gives the root at full float precision, and rounding to tolerance digits happens only at the end. No new parameters, same signature.

Tests:

  • fixed the existing assertion squareRoot(3, 1) from 1.8 to 1.7 (sqrt(3) = 1.732...)
  • added squareRoot(6) = 2, squareRoot(12) = 3, squareRoot(35) = 6, squareRoot(99) = 10, plus tolerance cases
  • edge cases: 0.25, 0.0001, 1e12, 1e300
  • every n from 1 to 1000 at tolerance 6 is checked against Math.sqrt

npm run lint and npm test pass (178 suites, 589 tests).

The loop stopped when |number - root^2| <= 10^-tolerance. That bounds the
error of the square, not of the root, so it could stop on an overestimate:
squareRoot(6) returned 3 and squareRoot(12) returned 4.

Iterate Newton's method until the approximation stops decreasing and
round only at the end. Fix the test that expected squareRoot(3, 1) to be
1.8 (sqrt(3) = 1.732...) and add regression tests.
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.

squareRoot(6) returns 3, squareRoot(12) returns 4; test expects squareRoot(3, 1) = 1.8 (correct: 1.7)

1 participant