It is my observation that (some) range queries are evaluated with an unnecessary precision (P): ranged units pick the closest unit as their target with very high precision (1 out of 4900m^2) for a 70m distant target.
Since 0ad involves large armies, this is a problem as it leads to unnecessary overkill (ie 100 archers shooting the closest unit)
What I propose here is a new 'CompareLength' function to evaluate relative distance to a flexible degree of precision using integer division:
Ie when using P = 5:
ranges: 13,14,15,16,19,22,29
results: 2, 2, 3, 3, 3, 4, 5
A sqrt is needed to fairly compare distances and reduce the excessive precision of 1 meter for large numbers. For this I used an approach involving a 2^x/2 guess and 1 or 2 updates in a while loop (https://stackoverflow.com/questions/34187171/fast-integer-square-root-approximation). Adjusting P allows for minimal iterations in the while loop (1 or 2), while still achieving close enough square roots (https://wildfiregames.com/forum/topic/118677-less-precise-sorting-in-range-manager/).
The behavior with P=3 for archers looks like this:
{F4459882}
To do:
x check that compared values are as expected after isqrtEst64() and integer division.
x Getting bit width is fast when using compiler builtins (__builtin_clz for GCC, __lzcnt for vs2017), so this needs to be made flexible. (used sdl bit width math)
x Check impacts of isqrtEst on gameplay, use isqrtEst64 more sparingly if needed
x Set up template value for precision, so P can vary for each unit.