The key mutation operator is random plus or minus exp(-c*rnd()). Where c is the so called precision and rnd() returns a uniform random float between 0 and 1. exp(0) = 1 and decreases rapidly with negative input exp(-1 )= 0.36787944117144, exp(-2) = 0.13533528323661, exp(-3) = =0.049787068367864. Using a precision of say 30 gives you a massive range of mutation strengths, yet with none being too infrequent.
The mutation operator is suitable for parameters between 0 and 1 (which you can then linearly map to suitable domain values for the function you want to optimize.) You have some choices if the mutation is too strong.
The mutation can also be obtained via fast bit hacks. if you take a 32 bit uniform random unsigned integer and clear the second most significant bit you can then view those raw bits as a 32 bit float. The sign bit is randomly plus or minus, the highest bit of the exponent is zero giving you mutation values between -2 and 2 with quite a high precision. Which is suitable for parameters between -1 and 1.
Unfortunately the precision is fixed in that case but there are other bit hacks alternatives to control the precision if needed.