Reputation: 528
Just for kicks, I'm trying to write a function that tells me all the roots of a number. I'm not sure on the math terminology, but I want the number and it's power that equals the given number.
For example, given the number 1024 I would get
{2:10, 4:5, 32:2}
(ie: 2^10 = 4^5 = 32^2 = 1024
).
I actually wrote a working algorithm but it runs into problems with floating point precision and I'm wondering if there's a better way.
This is the function I have now:
function findRoots(n) {
let result = {}
for (root = Math.floor(Math.sqrt(n)); root >= 2; root--) {
let test = n ** (1 / root)
if (Number.isInteger(test)) {
result[test] = root
}
}
return result
}
The output is an object where the property names are the roots and the values are the exponents.
But, for example, if I feed it 16807 (which should give me {7:5}
), I get nothing back because the method I'm using to test roots chokes on the float precision (ie 16807 ** (1/5) == 7.000000000000001
).
Is there a way to deal with the floats besides just lopping off some precision?
Upvotes: 1
Views: 249
Reputation: 908
You can use
if (Math.round(test) ** root == n) {
instead of
if (Number.isInteger(test)) {
Since we use Math.round(test)
, the roundoff error in test
will not cause any problems.
Upvotes: 2
Reputation: 14891
let test = +(n ** (1 / root)).toFixed(10)
should do the trick
function findRoots(n) {
let result = {}
for (root = Math.floor(Math.sqrt(n)); root >= 2; root--) {
let test = +(n ** (1 / root)).toFixed(10)
if (Number.isInteger(test)) {
result[test] = root
}
}
return result
}
console.log(findRoots(16807))
Upvotes: 0