Are there any alternatives to using Math.sqrt()
to get the square root of an unknown value?
For example:
var random = (Math.random() * (999 - 1)) + 1;
var sqrt = Math.sqrt(random);
I've heard that using Math.sqrt()
to get the square root of a number is a very slow operation, I'm just wondering if there are any faster ways I can get the square root of a random number. Any help with this would be greatly appreciated.
You can be sure that the fastest algorithm you will write your self is already implemented within Math.sqrt if not better .
There is an algorithm to go through the numbers till the middle (with some simply calculation) : Writing your own square root function
but as I said, it's probably implemented if not better.
You can try to look for some specific business/domain logic in order to reduce numbers range .
If the code you have there is the same code you are using you do not need the square root at all
var random = (Math.random() * (999 - 1)) + 1;
var sqrt = Math.sqrt(random);
Could be
var sqrt = (Math.random() * ( 31.6069612586)) + 1;
var random = sqrt * sqrt ;
Multiplication is much faster than sqrt so the code should be similar
Note the square root of 998 can be pre calculated like above to make it a one time operation rather than each run
Your distribution with sqrt
is not equal, as you see with the count. For getting the same distribution, you would need a factor which changes the distribution. The factor is dependent to the random number. There is no short cut.
function getRandom() {
return Math.sqrt((Math.random() * (999 - 1)) + 1);
}
var i, r,
o = {};
for (i = 0; i < 32; i++) {
o[i] = 0;
}
for (i = 0; i < 100000; i++) {
o[Math.floor(getRandom())]++;
}
console.log(o);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Do not know how your sqrt
is implemented (not a javascript coder) so what is faster I can only speculate but there are few fast methods out there using "magic numbers" for IEEE 754 float/double
formats and also for integers
for example like in Quake3. That works more or less precise with just few ops on defined intervals and are most likely faster then your sqrt but usable only on specific intervals.
Usual sqrt
implementations are done by:
approximation polynomial
usually Taylor series, Chebyshev, etc expansions are used and the number of therms is dependent on target accuracy. Not all math functions can be computed like this.
iterative approximation
there are few methods like Newton, Babylonian, etc which usually converge fast enough so no need to use too much therms. My bet is your sqrt
use Newtonian approximation.
There are also binary search based computations
- Power by squaring for negative exponents
Binary search requires the same count of iterations then used bits of number result which is usually more then therms used in approximation methods mentioned above. But binary search for sqrt has one huge advantage and that is it can be done without multiplication (which is significant for bignums...)
- How to get a square root for 32 bit input in one clock cycle only?
There are also other search approximations like:
- How approximation search works
algebraically using log2,exp2
you can compute pow
from log2,exp2
directly and sqrt(x)=pow(x,0.5)
so see
- How Math.Pow (and so on) actually works
LUT
You can use piecewise interpolation with precomputed look up tables.
hybrid methods
You can combine more methods together like estimate result with low accuracy approximation polynomial and then search around it (just few bits) with binary search ... But this is meaningful only for "big" numbers (in manner of bits)...
some math operations and constants can be computed with PCA
but I see no point to use it in your case...
Also for more info take a look at related QA:
- How is the square root function implemented?
Do not know what are you computing but fastest sqrt
is when you do not compute it at all. Many computations and algorithms can be rewritten so they do not need to use sqrt
at all or at least not that often (like comparing distances^2 etc...).
For examle if you want to do:
x = Random();
y = sqrt(x);
You can rewrite it to:
y= Random();
x = y*y;
but beware the randomness properties are not the same !!!
I don't think you can get any faster than the built in pre-compiled code yet for your information below you can find the algorithm on how you might get the square root of a number with pure JS.
It's pretty fast but since it's recursive it will most probably do somewhat slower than it's iterative version. Iterative implementation is up to you.
var sqrt = (n, u = n, d = n-1 ? n/u : 1) => n ? (u === (u+d)/2) && (d === n/u) ? d : sqrt(n,(u+d)/2, n/u) : 0,
s = 0;
console.time("sqrt");
var s = sqrt(9876543210*9876543210);
console.timeEnd("sqrt");
console.log(s);
console.time("sqrt");
var s = sqrt(98765.4321*98765.4321);
console.timeEnd("sqrt");
console.log(s);
It utilizes the Babylonian method.