therks
therks

Reputation: 528

Javascript: Find all root integers of a number

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

Answers (2)

yao99
yao99

Reputation: 908

You can use

if (Math.round(test) ** root == n) {

instead of

if (Number.isInteger(test)) {

Proof

test = n^{1/root}

\Rightarrow {test}^{root} = n

\Rightarrow round({test})^{root} = n \Leftrightarrow {test} \in N

Since we use Math.round(test), the roundoff error in test will not cause any problems.

Upvotes: 2

hgb123
hgb123

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

Related Questions