There's a very handy and fast method of finding integer square roots; I'm sure you could get this to work with fixed point:
unsigned long isqrt(v) unsigned long v; { register long t = 1L<<30, r = 0, s; # define STEP(k) s = t + r; r>>= 1; if (s <= v) { v -= s; r |= t;} STEP(15); t >>= 2; STEP(14); t >>= 2; STEP(13); t >>= 2; STEP(12); t >>= 2; STEP(11); t >>= 2; STEP(10); t >>= 2; STEP(9); t >>= 2; STEP(8); t >>= 2; STEP(7); t >>= 2; STEP(6); t >>= 2; STEP(5); t >>= 2; STEP(4); t >>= 2; STEP(3); t >>= 2; STEP(2); t >>= 2; STEP(1); t >>= 2; STEP(0); return (unsigned long)r; }