Here is a small improvement I can suggest. First - start iterating from 0. Second - exit loop when the square of root candidate exceeds the number.
function squareroot(number) {
for (var i = 0; i * i <= number; i++) {
if (i * i === number)
return i;
}
return number; // don't know if you should have this line in case nothing found
}
This algo will work in O(√number) time comparing to initial O(n) which is indeed performance improvement that you asked.
Edit #1
Just even more efficient solution would be to binary search the answer as @Spektre suggested. It is known that x2 is increasing function.
function squareroot(number) {
var lo = 0, hi = number;
while(lo <= hi) {
var mid = Math.floor((lo + hi) / 2);
if(mid * mid > number) hi = mid - 1;
else lo = mid + 1;
}
return hi;
}
This algo has O(log(number)) running time complexity.
Answer from Ivan Gritsenko on Stack OverflowHere is a small improvement I can suggest. First - start iterating from 0. Second - exit loop when the square of root candidate exceeds the number.
function squareroot(number) {
for (var i = 0; i * i <= number; i++) {
if (i * i === number)
return i;
}
return number; // don't know if you should have this line in case nothing found
}
This algo will work in O(√number) time comparing to initial O(n) which is indeed performance improvement that you asked.
Edit #1
Just even more efficient solution would be to binary search the answer as @Spektre suggested. It is known that x2 is increasing function.
function squareroot(number) {
var lo = 0, hi = number;
while(lo <= hi) {
var mid = Math.floor((lo + hi) / 2);
if(mid * mid > number) hi = mid - 1;
else lo = mid + 1;
}
return hi;
}
This algo has O(log(number)) running time complexity.
function squareRoot(n){
var avg=(a,b)=>(a+b)/2,c=5,b;
for(let i=0;i<20;i++){
b=n/c;
c=avg(b,c);
}
return c;
}
This will return the square root by repeatedly finding the average.
var result1 = squareRoot(25) //5
var result2 = squareRoot(100) //10
var result3 = squareRoot(15) //3.872983346207417
JSFiddle: https://jsfiddle.net/L5bytmoz/12/
Videos
Is there a way to calculate square roots in JavaScript without Math.sqrt()?
What is Math.sqrt() in JavaScript?
Why would you manually calculate a square root instead of using Math.sqrt()?
You could take xi (x) and the new value of xi + 1 (x1) and check if the values are equal. Then end the series and return that value.
For starting, you need an apporopriate value like the half of the given value.
function sqrt(a) {
var x,
x1 = a / 2;
do {
x = x1;
x1 = (x + (a / x)) / 2;
} while (x !== x1);
return x;
}
console.log(sqrt (2)); // 1.414
console.log(sqrt (9)); // 3
console.log(sqrt (25)); // 5
You can also use bisection - a more general method for solving problems:
var sqrt = function(n) {
if (n<0) {
throw "are you kidding?! we are REAL here.";
}
if (n === 0) {
return 0;
}
var bisect = function(l,r) {
var avg = (l+r)/2;
if (r-l<0.00000001) {
return (l+r)/2;
}
if (avg*avg > n) {
return bisect(l, avg);
} else if (avg*avg < n) {
return bisect(avg, r);
}
}
return bisect(0, n < 1 ? 1 : n);
}
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 .
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
sqrtuse 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,exp2you can compute
powfromlog2,exp2directly andsqrt(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 !!!
You can square each number and check to see if the result is less than the maximum.
function getNumbersWithSquareRoots(max) {
const arrNum = [];
for (let i = 0; i < max; i++) {
var square = i * i;
if (square < max) {
arrNum.push(square);
}
else {
break;
}
}
return arrNum;
}
The else is only there to break out of the loop once you've gone beyond the maximum.
This pushes the numbers 0 through 200 into my empty array. What I need my code to do is go through the array and get every number that can be a square root.
No, that's the wrong approach. Don't go through 200 numbers and try to find out which of them is square (has an integer square root). Instead, loop and put only square numbers in the array in the first place! That is much simpler and more efficient.
Can you use something like this?
Math.pow(n, 1/root);
eg.
Math.pow(25, 1/2) == 5
The nth root of x is the same as x to the power of 1/n. You can simply use Math.pow:
var original = 1000;
var fourthRoot = Math.pow(original, 1/4);
original == Math.pow(fourthRoot, 4); // (ignoring floating-point error)
I am new to HTML so I was trying to make calculator only with HTML and CSS. BUT, just I realized
onclick="display.value=eval(sqrt(display.value))"
does not work. Please help and let me know how to fix it.