stop the integer square root from spinning forever

newton's method in integers can settle into a two-value cycle rather
than a fixed point, and the loop guard was "the value changed", which
such a cycle satisfies for ever. it ran under the session lock inside a
spawned task, so the worker never reached a yield point and the runtime
could not shut down - which is why ctrl-c printed "shutdown requested"
and then hung.

the guard is now "stopped decreasing", which is the converging form.
checked against the exact integer square root across the small range and
the boundaries, including the 46340 saturation edge and INT_MAX.
This commit is contained in:
WiseDev 2026-08-23 14:07:03 +03:00
parent 9f1f9a7cef
commit 4239680f53

View file

@ -90,11 +90,11 @@ pub fn integer_sqrt(value: i64) -> i64 {
if value <= 0 {
return 0;
}
let mut root = value.min(46340);
let mut previous = 0;
while root != previous {
previous = root;
root = (root + value / root) / 2;
let mut root = value;
let mut next = (root + 1) / 2;
while next < root {
root = next;
next = (root + value / root) / 2;
}
root
}