Richard Lyons has described magnitude approximation in his books and online. He provides a fine explanation of the approximation errors. Below are two Bluespec SystemVerilog (BSV) functions implementing that technque. They are stateless (require no storage); but have been shown to run over 400 MHz in RTL on 40nm FPGAs. The use of a 18b UInt precision was chosen for clarity; the functions could easily be width-type polymorphic in BSV.
// |V| = Max + Min/2 function UInt#(18) magEst1(Complex#(UInt#(18)) c); if (c.rel > c.img) return( c.rel + c.img/2); else return( c.rel/2 + c.img); endfunction // |V| = 15(Max + Min/2)/16 function UInt#(18) magEst2(Complex#(UInt#(18)) c); let v = magEst1(c); return( v - v/16); endfunction